0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034 #include <ndrx_config.h>
0035 #include <string.h>
0036 #include <stdio.h>
0037 #include <stdlib.h>
0038 #include <memory.h>
0039 #include <time.h>
0040 #include <sys/time.h>
0041 #include <unistd.h>
0042 #include <stdarg.h>
0043
0044 #include <ndrstandard.h>
0045 #include <ndebug.h>
0046 #include <nstdutil.h>
0047 #include <sys_unix.h>
0048 #include <exbase64.h>
0049
0050
0051
0052
0053
0054
0055
0056 static char M_encoding_table_xa[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
0057 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
0058 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
0059 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
0060 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
0061 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
0062 'w', 'x', 'y', 'z', '0', '1', '2', '3',
0063 '4', '5', '6', '7', '8', '9', '+', '_'};
0064
0065 static char M_encoding_table_normal[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
0066 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
0067 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
0068 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
0069 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
0070 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
0071 'w', 'x', 'y', 'z', '0', '1', '2', '3',
0072 '4', '5', '6', '7', '8', '9', '+', '/'};
0073
0074
0075 static char M_decoding_table_xa[] =
0076 {
0077 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0078 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0079 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00,
0080 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0081 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
0082 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x00, 0x00, 0x00, 0x00, 0x3f,
0083 0x00, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
0084 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00,
0085 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0086 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0087 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0088 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0089 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0090 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0091 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0092 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
0093 };
0094
0095
0096 static char M_decoding_table_normal[] =
0097 {
0098 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0099 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0100 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x3f,
0101 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0102 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
0103 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00,
0104 0x00, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
0105 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00,
0106 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0107 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0108 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0109 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0110 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0111 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0112 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0113 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
0114 };
0115
0116 static int mod_table[] = {0, 2, 1};
0117
0118
0119 exprivate char * build_decoding_table(char *encoding_table);
0120
0121
0122
0123 exprivate char * ndrx_b64encode(const unsigned char *data,
0124 size_t input_length,
0125 size_t *output_length,
0126 char *encoded_data,
0127 char *encoding_table);
0128
0129
0130 exprivate unsigned char *ndrx_b64decode(unsigned char *data,
0131 size_t input_length,
0132 size_t *output_length,
0133 char *decoded_data,
0134 char *encoding_table);
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145 expublic char * ndrx_xa_base64_encode(unsigned char *data,
0146 size_t input_length,
0147 size_t *output_length,
0148 char *encoded_data)
0149 {
0150 return ndrx_b64encode(data, input_length, output_length,
0151 encoded_data, M_encoding_table_xa);
0152 }
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162 expublic unsigned char *ndrx_xa_base64_decode(unsigned char *data,
0163 size_t input_length,
0164 size_t *output_length,
0165 char *decoded_data)
0166 {
0167 return ndrx_b64decode((unsigned char *)data, input_length, output_length,
0168 decoded_data, (char *)M_decoding_table_xa);
0169 }
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181 char * ndrx_base64_encode(unsigned char *data,
0182 size_t input_length,
0183 size_t *output_length,
0184 char *encoded_data)
0185 {
0186 return ndrx_b64encode(data, input_length, output_length,
0187 encoded_data, M_encoding_table_normal);
0188 }
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198 unsigned char *ndrx_base64_decode(const char *data,
0199 size_t input_length,
0200 size_t *output_length,
0201 char *decoded_data)
0202 {
0203 return ndrx_b64decode((unsigned char *)data, input_length, output_length,
0204 decoded_data, (char *)M_decoding_table_normal);
0205 }
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215 exprivate char * ndrx_b64encode(const unsigned char *data,
0216 size_t input_length,
0217 size_t *output_length,
0218 char *encoded_data,
0219 char *encoding_table)
0220 {
0221 int i;
0222 int j;
0223 size_t tmp_len;
0224
0225
0226 tmp_len = 4 * ((input_length + 2) / 3);
0227
0228 if (*output_length > 0 && *output_length < (tmp_len+1) )
0229 {
0230 NDRX_LOG(log_error, "Failed to encode data len incl EOS %d but buffer sz %d",
0231 (int)(tmp_len+1), (int)*output_length);
0232 return NULL;
0233 }
0234
0235 *output_length = tmp_len;
0236
0237
0238
0239
0240
0241
0242
0243 for (i = 0, j = 0; i < input_length;)
0244 {
0245
0246 uint32_t octet_a = i < input_length ? (unsigned char)data[i++] : 0;
0247 uint32_t octet_b = i < input_length ? (unsigned char)data[i++] : 0;
0248 uint32_t octet_c = i < input_length ? (unsigned char)data[i++] : 0;
0249
0250 uint32_t triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c;
0251
0252 encoded_data[j++] = encoding_table[(triple >> 3 * 6) & 0x3F];
0253 encoded_data[j++] = encoding_table[(triple >> 2 * 6) & 0x3F];
0254 encoded_data[j++] = encoding_table[(triple >> 1 * 6) & 0x3F];
0255 encoded_data[j++] = encoding_table[(triple >> 0 * 6) & 0x3F];
0256 }
0257
0258 for (i = 0; i < mod_table[input_length % 3]; i++)
0259 encoded_data[*output_length - 1 - i] = '=';
0260
0261 encoded_data[*output_length] = EXEOS;
0262
0263
0264 (*output_length)++;
0265
0266 return encoded_data;
0267 }
0268
0269
0270
0271
0272
0273
0274
0275
0276
0277 exprivate unsigned char *ndrx_b64decode(unsigned char *data,
0278 size_t input_length,
0279 size_t *output_length,
0280 char *decoded_data,
0281 char *decoding_table)
0282 {
0283
0284 int i;
0285 int j;
0286 size_t tmp_len;
0287
0288 if (input_length % 4 != 0)
0289 {
0290 NDRX_LOG(log_error, "Invalid input_length: %d!", input_length);
0291 return NULL;
0292 }
0293
0294 if (input_length <= 0)
0295 {
0296 NDRX_LOG(log_error, "Invalid input length %d <= 0!", input_length);
0297 return NULL;
0298 }
0299
0300 tmp_len = input_length / 4 * 3;
0301
0302
0303 if (data[input_length - 1] == '=') tmp_len--;
0304 if (data[input_length - 2] == '=') tmp_len--;
0305
0306 if (*output_length > 0 && *output_length < tmp_len)
0307 {
0308 NDRX_LOG(log_error, "Output buffer too short: Output buffer size: %d, "
0309 "but data output size: %d", (int)*output_length, (int)tmp_len);
0310 return NULL;
0311 }
0312
0313 *output_length = tmp_len;
0314
0315
0316
0317
0318
0319 for (i = 0, j = 0; i < input_length;) {
0320
0321 uint32_t sextet_a = data[i] == '=' ? 0 & i++ : decoding_table[data[i++]];
0322 uint32_t sextet_b = data[i] == '=' ? 0 & i++ : decoding_table[data[i++]];
0323 uint32_t sextet_c = data[i] == '=' ? 0 & i++ : decoding_table[data[i++]];
0324 uint32_t sextet_d = data[i] == '=' ? 0 & i++ : decoding_table[data[i++]];
0325
0326 uint32_t triple = (sextet_a << 3 * 6)
0327 + (sextet_b << 2 * 6)
0328 + (sextet_c << 1 * 6)
0329 + (sextet_d << 0 * 6);
0330
0331 if (j < *output_length) decoded_data[j++] = (triple >> 2 * 8) & 0xFF;
0332 if (j < *output_length) decoded_data[j++] = (triple >> 1 * 8) & 0xFF;
0333 if (j < *output_length) decoded_data[j++] = (triple >> 0 * 8) & 0xFF;
0334 }
0335
0336 return (unsigned char *)decoded_data;
0337 }
0338
0339 #if 0
0340
0341
0342
0343 exprivate char * build_decoding_table(char *encoding_table)
0344 {
0345 int i;
0346 char *ptr = NDRX_MALLOC(256);
0347
0348 memset(ptr, 0, 256);
0349
0350 for (i = 0; i < 64; i++)
0351 ptr[(unsigned char) encoding_table[i]] = i;
0352
0353 fprintf(stderr, "START\n");
0354 for (i=0; i< 256; i++)
0355 {
0356 fprintf(stderr, "0x%02x, ", ptr[i]);
0357
0358 if (0==(i+1)%16)
0359 {
0360 fprintf(stderr, "\n");
0361 }
0362
0363 }
0364 fprintf(stderr, "END\n");
0365 return ptr;
0366 }
0367 #endif
0368
0369 #if 0
0370
0371
0372
0373 exprivate void base64_cleanup(void)
0374 {
0375 NDRX_FREE(decoding_table);
0376 }
0377 #endif
0378
0379