1
/* Copyright (c) 2008 PrimeBase Technologies GmbH, Germany
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.
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.
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
19
* Created by Barry Leslie on 10/21/08.
31
static const u_char base64Map[64] = {
32
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
33
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
34
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
35
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
36
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
37
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
38
'w', 'x', 'y', 'z', '0', '1', '2', '3',
39
'4', '5', '6', '7', '8', '9', '+', '/'
42
static const u_char decodeBase64Map[128] = {
43
0XBF, 0XFF, 0XF2, 0X2C, 0XBF, 0XFF, 0XF2, 0X24,
44
0X0, 0X0, 0X2E, 0X4C, 0X0, 0X0, 0X0, 0X3,
45
0X0, 0X0, 0X0, 0X3, 0XBF, 0XFF, 0XF1, 0X40,
46
0X0, 0X0, 0X0, 0X50, 0X8F, 0XE1, 0X56, 0XD8,
47
0X0, 0X30, 0X6, 0XEC, 0X0, 0X30, 0X6, 0XF0,
48
0X0, 0X0, 0X2E, 0X3E, 0X0, 0X0, 0X0, 0X3F,
49
0X34, 0X35, 0X36, 0X37, 0X38, 0X39, 0X3A, 0X3B,
50
0X3C, 0X3D, 0X2C, 0X68, 0X90, 0X0, 0X17, 0XD8,
51
0XBF, 0X0, 0X1, 0X2, 0X3, 0X4, 0X5, 0X6,
52
0X7, 0X8, 0X9, 0XA, 0XB, 0XC, 0XD, 0XE,
53
0XF, 0X10, 0X11, 0X12, 0X13, 0X14, 0X15, 0X16,
54
0X17, 0X18, 0X19, 0X80, 0X0, 0X0, 0X0, 0X0,
55
0X0, 0X1A, 0X1B, 0X1C, 0X1D, 0X1E, 0X1F, 0X20,
56
0X21, 0X22, 0X23, 0X24, 0X25, 0X26, 0X27, 0X28,
57
0X29, 0X2A, 0X2B, 0X2C, 0X2D, 0X2E, 0X2F, 0X30,
58
0X31, 0X32, 0X33, 0X0, 0X90, 0X1B, 0XBA, 0X48,
62
static bool base64Encoded(const u_char *data, size_t len)
69
while ( i && data[i-1] == '=') i--;
74
for (; i ; i--, data++) {
79
return true; // Actually this isn't so much 'true' as 'maybe'
82
char *base64Encode(const void *data, size_t len)
84
u_char *wptr, *rptr, *encoding;
88
size = ((len + 2) / 3) * 4;
89
encoding = (u_char *) cs_malloc(size +1);
93
rptr = (u_char *) data;
96
wptr[0] = base64Map[rptr[0] >>2];
97
wptr[1] = base64Map[((rptr[0] & 0X03) <<4) + (rptr[1] >> 4)];
98
wptr[2] = base64Map[((rptr[1] & 0X0F) <<2) + (rptr[2] >> 6)];
99
wptr[3] = base64Map[(rptr[2] & 0X3F)];
106
wptr[0] = base64Map[rptr[0] >>2];
109
wptr[1] = base64Map[(rptr[0] & 0x03) << 4];
110
wptr[2] = wptr[3] = '=';
112
wptr[1] = base64Map[((rptr[0] & 0X03) <<4) + (rptr[1] >> 4)];
113
wptr[2] = base64Map[(rptr[1] & 0X0F) <<2];
119
return_((char*)encoding);
122
void *base64Decode(const char *data, size_t len)
125
u_char *wptr, *rptr, *decoding;
128
rptr = (u_char *) data;
130
if (!base64Encoded(rptr, len))
131
CSException::throwException(CS_CONTEXT, CS_ERR_GENERIC_ERROR, "String was not Base64 encoded.");
133
decoding = (u_char *) cs_malloc((len/ 4) * 3);
138
while (rptr[tail-1] == '=')
143
wptr[0] = ( ((decodeBase64Map[rptr[0]] << 2) & 0xFF) | ((decodeBase64Map[rptr[1]] >> 4) & 0x03) );
144
wptr[1] = ( ((decodeBase64Map[rptr[1]] << 4) & 0xFF) | ((decodeBase64Map[rptr[2]] >> 2) & 0x0F) );
145
wptr[2] = ( ((decodeBase64Map[rptr[2]] << 6) & 0xFF) | (decodeBase64Map[rptr[3]] & 0x3F) );
153
wptr[0] = ( ((decodeBase64Map[rptr[0]] << 2) & 0xFF) | ((decodeBase64Map[rptr[1]] >> 4) & 0x03) );
155
wptr[1] = ( ((decodeBase64Map[rptr[1]] << 4) & 0xFF) | ((decodeBase64Map[rptr[2]] >> 2) & 0x0F) );
162
//-----------------------------------------------------
163
void hmac_md5(u_char *text, size_t text_len, u_char *key, size_t key_len, Md5Digest *digest)
166
unsigned char k_ipad[65]; /* inner padding -
169
unsigned char k_opad[65]; /* outer padding -
172
unsigned char tk[16];
175
/* if key is longer than 64 bytes reset it to key=MD5(key) */
180
md5.md5_append(key, key_len);
181
md5.md5_digest(digest);
187
/* start out by storing key in pads */
188
memset(k_ipad, 0, sizeof(k_ipad));
189
memset(k_opad, 0, sizeof(k_opad));
191
memcpy(k_ipad, key, key_len);
192
memcpy(k_opad, key, key_len);
194
/* XOR key with ipad and opad values */
195
for (i=0; i<64; i++) {
200
* perform inner encoding
203
md5.md5_append(k_ipad, 64);
204
md5.md5_append(text, strlen(text));
205
md5.md5_digest(digest);
208
* perform outer encoding
211
md5.md5_append(k_opad, 64);
212
md5.md5_append((u_char*)digest, 16);
213
md5.md5_digest(digest);
219
//-----------------------------------------------------
220
void hmac_sha1(const char *text, const char *key, Sha1Digest *digest)
223
size_t key_len = strlen(key);
224
unsigned char k_ipad[65]; /* inner padding -
227
unsigned char k_opad[65]; /* outer padding -
232
/* if key is longer than 64 bytes reset it to key=MD5(key) */
237
sha1.sha1_input(key, key_len);
238
sha1.sha1_digest(digest);
240
key = (char *) digest->val;
244
/* start out by storing key in pads */
245
memset(k_ipad, 0, sizeof(k_ipad));
246
memset(k_opad, 0, sizeof(k_opad));
248
memcpy(k_ipad, key, key_len);
249
memcpy(k_opad, key, key_len);
251
/* XOR key with ipad and opad values */
252
for (i=0; i<64; i++) {
258
* perform inner encoding
261
sha1.sha1_input(k_ipad, 64);
262
sha1.sha1_input(text, strlen(text));
263
sha1.sha1_digest(digest);
267
* perform outer encoding
270
sha1.sha1_input(k_opad, 64);
271
sha1.sha1_input(digest, 20);
272
sha1.sha1_digest(digest);
276
//-----------------------------------------------------
277
CSString *signature(const char *text, const char *key)
281
CSString *signed_str;
283
memset(&digest, 0, sizeof(digest));
284
hmac_sha1(text, key, &digest);
286
encoding = base64Encode(digest.val, SHA1_HASH_SIZE);
287
signed_str = CSString::newString(encoding);
293
//-----------------------------------------------------
294
// Encode url unsafe characters
295
CSString *urlEncode(CSString *src)
297
const char *hex = "0123456789ABCDEF", *start, *ptr;
304
new_(url, CSStringBuffer(10));
307
start = ptr = src->getCString();
311
if (!isalnum(*ptr)) {
325
url->append(start, ptr-start);
327
encoded[1] = hex[*ptr/16];
328
encoded[2] = hex[*ptr%16];
329
url->append(encoded, 3);
334
url->append(start, ptr-start);
336
CSString *safe_str = CSString::newString(url->getCString());