jabberd2  2.6.1
base64.c
Go to the documentation of this file.
1 #ifdef HAVE_CONFIG_H
2 # include <config.h>
3 #endif
4 #include <stddef.h>
5 #ifdef HAVE_SSL
6 /* use OpenSSL functions when available */
7 #include <openssl/sha.h>
8 #include <openssl/hmac.h>
9 #include <openssl/evp.h>
10 #include <openssl/bio.h>
11 #include <openssl/buffer.h>
12 
13 #include "util.h"
14 
15 static const char gdtable[] =
16 {
17  64, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
18  128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
19  128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 62, 128, 128, 128, 63,
20  52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 128, 128, 128, 0, 128, 128,
21  128, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
22  15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 128, 128, 128, 128, 128,
23  128, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
24  41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 128, 128, 128, 128, 128,
25  128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
26  128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
27  128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
28  128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
29  128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
30  128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
31  128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
32  128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128
33 };
34 
35 int apr_base64_decode_len( const char *bufcoded, int buflen )
36 {
37  int count = 0;
38  int i;
39  for ( i = 0; i < buflen; ++i )
40  {
41  if ( gdtable[(int)bufcoded[i]] != 0x80 )
42  ++count;
43  }
44  return (((count + 3) / 4) * 3) + 1;
45 }
46 
47 int apr_base64_decode( char *decoded, const char *input, int length )
48 {
49  BIO *b64 = BIO_new(BIO_f_base64());
50  BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
51  BIO *bmem = BIO_new_mem_buf((void*)input, length);
52  bmem = BIO_push(b64, bmem);
53 
54  int ret = BIO_read(bmem, decoded, length);
55  BIO_free_all(bmem);
56 
57  return ret;
58 }
59 
60 int apr_base64_encode_len( int len )
61 {
62  return ((len + 2) / 3 * 4) + 1;
63 }
64 
65 int apr_base64_encode( char *encoded, const char *input, int length )
66 {
67  if ( ! length )
68  {
69  encoded[0] = 0;
70  return 1; /* length incl '\0' */
71  }
72 
73  BIO *b64 = BIO_new(BIO_f_base64());
74  BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
75  BIO *bmem = BIO_new(BIO_s_mem());
76  b64 = BIO_push(b64, bmem);
77 
78  BIO_write(b64, input, length);
79  BIO_flush(b64);
80 
81  BUF_MEM *bptr;
82  BIO_get_mem_ptr(b64, &bptr);
83  memcpy(encoded, bptr->data, bptr->length);
84  encoded[bptr->length] = 0;
85  int ret = bptr->length+1;
86  BIO_free_all(b64);
87 
88  return ret; /* length incl '\0' */
89 }
90 
91 #else
92 #warning OpenSSL functions for base64 not available
93 /* Licensed to the Apache Software Foundation (ASF) under one or more
94  * contributor license agreements. See the NOTICE file distributed with
95  * this work for additional information regarding copyright ownership.
96  * The ASF licenses this file to You under the Apache License, Version 2.0
97  * (the "License"); you may not use this file except in compliance with
98  * the License. You may obtain a copy of the License at
99  *
100  * http://www.apache.org/licenses/LICENSE-2.0
101  *
102  * Unless required by applicable law or agreed to in writing, software
103  * distributed under the License is distributed on an "AS IS" BASIS,
104  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
105  * See the License for the specific language governing permissions and
106  * limitations under the License.
107  */
108 
109 /* base64 encoder/decoder. Originally part of main/util.c
110  * but moved here so that support/ab and apr_sha1.c could
111  * use it. This meant removing the apr_palloc()s and adding
112  * ugly 'len' functions, which is quite a nasty cost.
113  */
114 
115 #include "util.h"
116 
117 /* aaaack but it's fast and const should make it shared text page. */
118 static const unsigned char pr2six[256] =
119 {
120  /* ASCII table */
121  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
122  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
123  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63,
124  52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64,
125  64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
126  15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64,
127  64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
128  41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64,
129  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
130  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
131  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
132  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
133  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
134  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
135  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
136  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
137 };
138 
139 int apr_base64_decode_len(const char *bufcoded, int buflen)
140 {
141  int nbytesdecoded;
142  register const unsigned char *bufin;
143  register int nprbytes;
144 
145  bufin = (const unsigned char *) bufcoded;
146  while (pr2six[*(bufin++)] <= 63 && buflen-- > 0);
147 
148  nprbytes = (bufin - (const unsigned char *) bufcoded) - 1;
149  nbytesdecoded = (((int)nprbytes + 3) / 4) * 3;
150 
151  return nbytesdecoded + 1;
152 }
153 
154 int apr_base64_decode_binary(unsigned char *bufplain, const char *bufcoded, int buflen);
155 
156 int apr_base64_decode(char *bufplain, const char *bufcoded, int buflen)
157 {
158  int len;
159 
160  len = apr_base64_decode_binary((unsigned char *) bufplain, bufcoded, buflen);
161  bufplain[len] = '\0';
162  return len;
163 }
164 
165 int apr_base64_decode_binary(unsigned char *bufplain,
166  const char *bufcoded, int buflen)
167 {
168  int nbytesdecoded;
169  register const unsigned char *bufin;
170  register unsigned char *bufout;
171  register int nprbytes;
172 
173  bufin = (const unsigned char *) bufcoded;
174  while (pr2six[*(bufin++)] <= 63 && buflen-- > 0);
175  nprbytes = (bufin - (const unsigned char *) bufcoded) - 1;
176  nbytesdecoded = (((int)nprbytes + 3) / 4) * 3;
177 
178  bufout = (unsigned char *) bufplain;
179  bufin = (const unsigned char *) bufcoded;
180 
181  while (nprbytes > 4) {
182  *(bufout++) =
183  (unsigned char) (pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4);
184  *(bufout++) =
185  (unsigned char) (pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2);
186  *(bufout++) =
187  (unsigned char) (pr2six[bufin[2]] << 6 | pr2six[bufin[3]]);
188  bufin += 4;
189  nprbytes -= 4;
190  }
191 
192  /* Note: (nprbytes == 1) would be an error, so just ingore that case */
193  if (nprbytes > 1) {
194  *(bufout++) =
195  (unsigned char) (pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4);
196  }
197  if (nprbytes > 2) {
198  *(bufout++) =
199  (unsigned char) (pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2);
200  }
201  if (nprbytes > 3) {
202  *(bufout++) =
203  (unsigned char) (pr2six[bufin[2]] << 6 | pr2six[bufin[3]]);
204  }
205 
206  nbytesdecoded -= (4 - (int)nprbytes) & 3;
207  return nbytesdecoded;
208 }
209 
210 static const char basis_64[] =
211  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
212 
214 {
215  return ((len + 2) / 3 * 4) + 1;
216 }
217 
218 int apr_base64_encode_binary(char *encoded, const unsigned char *string, int len);
219 
220 int apr_base64_encode(char *encoded, const char *string, int len)
221 {
222  return apr_base64_encode_binary(encoded, (const unsigned char *) string, len);
223 }
224 
225 int apr_base64_encode_binary(char *encoded,
226  const unsigned char *string, int len)
227 {
228  int i;
229  char *p;
230 
231  p = encoded;
232  for (i = 0; i < len - 2; i += 3) {
233  *p++ = basis_64[(string[i] >> 2) & 0x3F];
234  *p++ = basis_64[((string[i] & 0x3) << 4) |
235  ((int) (string[i + 1] & 0xF0) >> 4)];
236  *p++ = basis_64[((string[i + 1] & 0xF) << 2) |
237  ((int) (string[i + 2] & 0xC0) >> 6)];
238  *p++ = basis_64[string[i + 2] & 0x3F];
239  }
240  if (i < len) {
241  *p++ = basis_64[(string[i] >> 2) & 0x3F];
242  if (i == (len - 1)) {
243  *p++ = basis_64[((string[i] & 0x3) << 4)];
244  *p++ = '=';
245  }
246  else {
247  *p++ = basis_64[((string[i] & 0x3) << 4) |
248  ((int) (string[i + 1] & 0xF0) >> 4)];
249  *p++ = basis_64[((string[i + 1] & 0xF) << 2)];
250  }
251  *p++ = '=';
252  }
253 
254  *p++ = '\0';
255  return (int)(p - encoded);
256 }
257 #endif /* HAVE_SSL */
258 
259 /* convenience functions for j2 */
260 char *b64_encode(char *buf, int len) {
261  int elen;
262  char *out;
263 
264  if(len == 0)
265  len = strlen(buf);
266 
267  elen = apr_base64_encode_len(len);
268  out = (char *) malloc(sizeof(char) * (elen + 1));
269 
270  apr_base64_encode(out, buf, len);
271 
272  return out;
273 }
274 
275 char *b64_decode(char *buf) {
276  int blen;
277  int elen;
278  char *out;
279 
280  blen = strlen(buf);
281  elen = apr_base64_decode_len(buf, blen);
282  out = (char *) malloc(sizeof(char) * (elen + 1));
283 
284  apr_base64_decode(out, buf, blen);
285 
286  return out;
287 }
int apr_base64_encode_binary(char *encoded, const unsigned char *string, int len)
Definition: base64.c:225
char * b64_encode(char *buf, int len)
Definition: base64.c:260
int apr_base64_decode(char *bufplain, const char *bufcoded, int buflen)
Definition: base64.c:156
int apr_base64_decode_len(const char *bufcoded, int buflen)
Definition: base64.c:139
int apr_base64_encode(char *encoded, const char *string, int len)
Definition: base64.c:220
static const unsigned char pr2six[256]
Definition: base64.c:118
char * b64_decode(char *buf)
Definition: base64.c:275
int apr_base64_encode_len(int len)
Definition: base64.c:213
int apr_base64_decode_binary(unsigned char *bufplain, const char *bufcoded, int buflen)
Definition: base64.c:165
static const char basis_64[]
Definition: base64.c:210