| 1 | /* |
|---|
| 2 | * QuteCom SIP stack |
|---|
| 3 | * Copyright (C) 2010 Mbdsys |
|---|
| 4 | * |
|---|
| 5 | * This program is free software; you can redistribute it and/or modify |
|---|
| 6 | * it under the terms of the GNU General Public License as published by |
|---|
| 7 | * the Free Software Foundation; either version 2 of the License, or |
|---|
| 8 | * (at your option) any later version. |
|---|
| 9 | * |
|---|
| 10 | * This program is distributed in the hope that it will be useful, |
|---|
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 13 | * GNU General Public License for more details. |
|---|
| 14 | * |
|---|
| 15 | * You should have received a copy of the GNU General Public License |
|---|
| 16 | * along with this program; if not, write to the Free Software |
|---|
| 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|---|
| 18 | */ |
|---|
| 19 | |
|---|
| 20 | /* |
|---|
| 21 | * adapted from Bob Trower work: http://base64.sourceforge.net/b64.c |
|---|
| 22 | */ |
|---|
| 23 | |
|---|
| 24 | #include "eXosip2.h" |
|---|
| 25 | |
|---|
| 26 | #include <stdlib.h> |
|---|
| 27 | |
|---|
| 28 | /* |
|---|
| 29 | ** Translation Table as described in RFC1113 |
|---|
| 30 | */ |
|---|
| 31 | static const char cb64 [] = |
|---|
| 32 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" ; |
|---|
| 33 | |
|---|
| 34 | /* |
|---|
| 35 | ** encode 3 8-bit binary bytes as 4 '6-bit' characters |
|---|
| 36 | */ |
|---|
| 37 | static void base64_encode_block |
|---|
| 38 | ( |
|---|
| 39 | unsigned char in [3], |
|---|
| 40 | int in_length, |
|---|
| 41 | unsigned char out [4] |
|---|
| 42 | ) |
|---|
| 43 | { |
|---|
| 44 | out [0] = cb64 [in [0] >> 2] ; |
|---|
| 45 | out [1] = cb64 [((in [0] & 0x03) << 4) | ((in [1] & 0xf0) >> 4)] ; |
|---|
| 46 | out [2] = (unsigned char) (in_length > 1 ? |
|---|
| 47 | cb64 [((in [1] & 0x0f) << 2) | ((in [2] & 0xc0) >> 6)] : |
|---|
| 48 | '=') ; |
|---|
| 49 | out [3] = (unsigned char) (in_length > 2 ? |
|---|
| 50 | cb64 [in [2] & 0x3f] : |
|---|
| 51 | '=') ; |
|---|
| 52 | } |
|---|
| 53 | |
|---|
| 54 | /* |
|---|
| 55 | ** base64 encode a stream adding padding and line breaks as per spec. |
|---|
| 56 | */ |
|---|
| 57 | int base64_encode |
|---|
| 58 | ( |
|---|
| 59 | const void * in, |
|---|
| 60 | int in_length, |
|---|
| 61 | char * out, |
|---|
| 62 | int out_size, |
|---|
| 63 | int line_size |
|---|
| 64 | ) |
|---|
| 65 | { |
|---|
| 66 | int in_index = 0, out_index = 0 ; |
|---|
| 67 | int block_count, block_index ; |
|---|
| 68 | unsigned char in_block [3], out_block [4] ; |
|---|
| 69 | int in_block_index, in_block_length ; |
|---|
| 70 | int out_block_index ; |
|---|
| 71 | |
|---|
| 72 | if (line_size > 0 && line_size < 4) |
|---|
| 73 | { |
|---|
| 74 | return -1 ; |
|---|
| 75 | } |
|---|
| 76 | |
|---|
| 77 | block_count = (in_length + 2) / 3 ; |
|---|
| 78 | if (out_size < block_count * 4 + 1) |
|---|
| 79 | { |
|---|
| 80 | return -1 ; |
|---|
| 81 | } |
|---|
| 82 | |
|---|
| 83 | for (block_index = 0 ; block_index < block_count ; block_index ++) |
|---|
| 84 | { |
|---|
| 85 | if |
|---|
| 86 | ( |
|---|
| 87 | line_size > 0 && |
|---|
| 88 | block_index > 0 && |
|---|
| 89 | block_index % (line_size / 4) == 0 |
|---|
| 90 | ) |
|---|
| 91 | { |
|---|
| 92 | out [out_index ++] = '\r' ; |
|---|
| 93 | out [out_index ++] = '\n' ; |
|---|
| 94 | } |
|---|
| 95 | |
|---|
| 96 | in_block_length = 0 ; |
|---|
| 97 | for (in_block_index = 0 ; in_block_index < 3 ; in_block_index ++) |
|---|
| 98 | { |
|---|
| 99 | if (in_index < in_length) |
|---|
| 100 | { |
|---|
| 101 | in_block [in_block_index] = ((unsigned char *) in) [in_index] ; |
|---|
| 102 | in_block_length ++ ; |
|---|
| 103 | } |
|---|
| 104 | else |
|---|
| 105 | { |
|---|
| 106 | in_block [in_block_index] = 0 ; |
|---|
| 107 | } |
|---|
| 108 | in_index ++ ; |
|---|
| 109 | } |
|---|
| 110 | |
|---|
| 111 | base64_encode_block (in_block, in_block_length, out_block) ; |
|---|
| 112 | |
|---|
| 113 | for (out_block_index = 0 ; out_block_index < 4 ; out_block_index ++) |
|---|
| 114 | { |
|---|
| 115 | out [out_index ++] = out_block [out_block_index] ; |
|---|
| 116 | } |
|---|
| 117 | } |
|---|
| 118 | out [out_index ++] = 0 ; |
|---|
| 119 | |
|---|
| 120 | return out_index ; |
|---|
| 121 | } |
|---|