25397cc4097bbd158ae2bb827ef7a45225be8fcf
[bluesky.git] / libs3-1.4 / src / util.c
1 /** **************************************************************************
2  * util.c
3  * 
4  * Copyright 2008 Bryan Ischo <bryan@ischo.com>
5  * 
6  * This file is part of libs3.
7  * 
8  * libs3 is free software: you can redistribute it and/or modify it under the
9  * terms of the GNU General Public License as published by the Free Software
10  * Foundation, version 3 of the License.
11  *
12  * In addition, as a special exception, the copyright holders give
13  * permission to link the code of this library and its programs with the
14  * OpenSSL library, and distribute linked combinations including the two.
15  *
16  * libs3 is distributed in the hope that it will be useful, but WITHOUT ANY
17  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
19  * details.
20  *
21  * You should have received a copy of the GNU General Public License version 3
22  * along with libs3, in a file named COPYING.  If not, see
23  * <http://www.gnu.org/licenses/>.
24  *
25  ************************************************************************** **/
26
27 #include <ctype.h>
28 #include <string.h>
29 #include "util.h"
30
31
32 // Convenience utility for making the code look nicer.  Tests a string
33 // against a format; only the characters specified in the format are
34 // checked (i.e. if the string is longer than the format, the string still
35 // checks out ok).  Format characters are:
36 // d - is a digit
37 // anything else - is that character
38 // Returns nonzero the string checks out, zero if it does not.
39 static int checkString(const char *str, const char *format)
40 {
41     while (*format) {
42         if (*format == 'd') {
43             if (!isdigit(*str)) {
44                 return 0;
45             }
46         }
47         else if (*str != *format) {
48             return 0;
49         }
50         str++, format++;
51     }
52
53     return 1;
54 }
55
56
57 int urlEncode(char *dest, const char *src, int maxSrcSize)
58 {
59     static const char *urlSafe = "-_.!~*'()/";
60     static const char *hex = "0123456789ABCDEF";
61
62     int len = 0;
63
64     if (src) while (*src) {
65         if (++len > maxSrcSize) {
66             *dest = 0;
67             return 0;
68         }
69         const char *urlsafe = urlSafe;
70         int isurlsafe = 0;
71         while (*urlsafe) {
72             if (*urlsafe == *src) {
73                 isurlsafe = 1;
74                 break;
75             }
76             urlsafe++;
77         }
78         if (isurlsafe || isalnum(*src)) {
79             *dest++ = *src++;
80         }
81         else if (*src == ' ') {
82             *dest++ = '+';
83             src++;
84         }
85         else {
86             *dest++ = '%';
87             *dest++ = hex[*src / 16];
88             *dest++ = hex[*src % 16];
89             src++;
90         }
91     }
92
93     *dest = 0;
94
95     return 1;
96 }
97
98
99 int64_t parseIso8601Time(const char *str)
100 {
101     // Check to make sure that it has a valid format
102     if (!checkString(str, "dddd-dd-ddTdd:dd:dd")) {
103         return -1;
104     }
105
106 #define nextnum() (((*str - '0') * 10) + (*(str + 1) - '0'))
107
108     // Convert it
109     struct tm stm;
110     memset(&stm, 0, sizeof(stm));
111
112     stm.tm_year = (nextnum() - 19) * 100;
113     str += 2;
114     stm.tm_year += nextnum();
115     str += 3;
116
117     stm.tm_mon = nextnum() - 1;
118     str += 3;
119
120     stm.tm_mday = nextnum();
121     str += 3;
122
123     stm.tm_hour = nextnum();
124     str += 3;
125
126     stm.tm_min = nextnum();
127     str += 3;
128
129     stm.tm_sec = nextnum();
130     str += 2;
131
132     stm.tm_isdst = -1;
133     
134     int64_t ret = mktime(&stm);
135
136     // Skip the millis
137
138     if (*str == '.') {
139         str++;
140         while (isdigit(*str)) {
141             str++;
142         }
143     }
144     
145     if (checkString(str, "-dd:dd") || checkString(str, "+dd:dd")) {
146         int sign = (*str++ == '-') ? -1 : 1;
147         int hours = nextnum();
148         str += 3;
149         int minutes = nextnum();
150         ret += (-sign * (((hours * 60) + minutes) * 60));
151     }
152     // Else it should be Z to be a conformant time string, but we just assume
153     // that it is rather than enforcing that
154
155     return ret;
156 }
157
158
159 uint64_t parseUnsignedInt(const char *str)
160 {
161     // Skip whitespace
162     while (is_blank(*str)) {
163         str++;
164     }
165
166     uint64_t ret = 0;
167
168     while (isdigit(*str)) {
169         ret *= 10;
170         ret += (*str++ - '0');
171     }
172
173     return ret;
174 }
175
176
177 int base64Encode(const unsigned char *in, int inLen, char *out)
178 {
179     static const char *ENC = 
180         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
181
182     char *original_out = out;
183
184     while (inLen) {
185         // first 6 bits of char 1
186         *out++ = ENC[*in >> 2];
187         if (!--inLen) {
188             // last 2 bits of char 1, 4 bits of 0
189             *out++ = ENC[(*in & 0x3) << 4];
190             *out++ = '=';
191             *out++ = '=';
192             break;
193         }
194         // last 2 bits of char 1, first 4 bits of char 2
195         *out++ = ENC[((*in & 0x3) << 4) | (*(in + 1) >> 4)];
196         in++;
197         if (!--inLen) {
198             // last 4 bits of char 2, 2 bits of 0
199             *out++ = ENC[(*in & 0xF) << 2];
200             *out++ = '=';
201             break;
202         }
203         // last 4 bits of char 2, first 2 bits of char 3
204         *out++ = ENC[((*in & 0xF) << 2) | (*(in + 1) >> 6)];
205         in++;
206         // last 6 bits of char 3
207         *out++ = ENC[*in & 0x3F];
208         in++, inLen--;
209     }
210
211     return (out - original_out);
212 }
213
214
215 #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
216
217 #define blk0L(i) (block->l[i] = (rol(block->l[i], 24) & 0xFF00FF00)     \
218                   | (rol(block->l[i], 8) & 0x00FF00FF))
219
220 #define blk0B(i) (block->l[i])
221
222 #define blk(i) (block->l[i & 15] = rol(block->l[(i + 13) & 15] ^        \
223                                        block->l[(i + 8) & 15] ^         \
224                                        block->l[(i + 2) & 15] ^         \
225                                        block->l[i & 15], 1))
226
227 #define R0_L(v, w, x, y, z, i)                                          \
228     z += ((w & (x ^ y)) ^ y) + blk0L(i) + 0x5A827999 + rol(v, 5);       \
229     w = rol(w, 30);
230 #define R0_B(v, w, x, y, z, i)                                          \
231     z += ((w & (x ^ y)) ^ y) + blk0B(i) + 0x5A827999 + rol(v, 5);       \
232     w = rol(w, 30);
233 #define R1(v, w, x, y, z, i)                                            \
234     z += ((w & (x ^ y)) ^ y) + blk(i) + 0x5A827999 + rol(v, 5);         \
235     w = rol(w, 30);
236 #define R2(v, w, x, y, z, i)                                            \
237     z += (w ^ x ^ y) + blk(i) + 0x6ED9EBA1 + rol(v, 5);                 \
238     w = rol(w, 30);
239 #define R3(v, w, x, y, z, i)                                            \
240     z += (((w | x) & y) | (w & x)) + blk(i) + 0x8F1BBCDC + rol(v, 5);   \
241     w = rol(w, 30);
242 #define R4(v, w, x, y, z, i)                                            \
243     z += (w ^ x ^ y) + blk(i) + 0xCA62C1D6 + rol(v, 5);                 \
244     w = rol(w, 30);
245
246 #define R0A_L(i) R0_L(a, b, c, d, e, i)
247 #define R0B_L(i) R0_L(b, c, d, e, a, i)
248 #define R0C_L(i) R0_L(c, d, e, a, b, i)
249 #define R0D_L(i) R0_L(d, e, a, b, c, i)
250 #define R0E_L(i) R0_L(e, a, b, c, d, i)
251
252 #define R0A_B(i) R0_B(a, b, c, d, e, i)
253 #define R0B_B(i) R0_B(b, c, d, e, a, i)
254 #define R0C_B(i) R0_B(c, d, e, a, b, i)
255 #define R0D_B(i) R0_B(d, e, a, b, c, i)
256 #define R0E_B(i) R0_B(e, a, b, c, d, i)
257
258 #define R1A(i) R1(a, b, c, d, e, i)
259 #define R1B(i) R1(b, c, d, e, a, i)
260 #define R1C(i) R1(c, d, e, a, b, i)
261 #define R1D(i) R1(d, e, a, b, c, i)
262 #define R1E(i) R1(e, a, b, c, d, i)
263
264 #define R2A(i) R2(a, b, c, d, e, i)
265 #define R2B(i) R2(b, c, d, e, a, i)
266 #define R2C(i) R2(c, d, e, a, b, i)
267 #define R2D(i) R2(d, e, a, b, c, i)
268 #define R2E(i) R2(e, a, b, c, d, i)
269
270 #define R3A(i) R3(a, b, c, d, e, i)
271 #define R3B(i) R3(b, c, d, e, a, i)
272 #define R3C(i) R3(c, d, e, a, b, i)
273 #define R3D(i) R3(d, e, a, b, c, i)
274 #define R3E(i) R3(e, a, b, c, d, i)
275
276 #define R4A(i) R4(a, b, c, d, e, i)
277 #define R4B(i) R4(b, c, d, e, a, i)
278 #define R4C(i) R4(c, d, e, a, b, i)
279 #define R4D(i) R4(d, e, a, b, c, i)
280 #define R4E(i) R4(e, a, b, c, d, i)
281
282
283 static void SHA1_transform(uint32_t state[5], const unsigned char buffer[64])
284 {
285     uint32_t a, b, c, d, e;
286
287     typedef union {
288         unsigned char c[64];
289         uint32_t l[16];
290     } u;
291
292     unsigned char w[64];
293     u *block = (u *) w;
294
295     memcpy(block, buffer, 64);
296
297     a = state[0];
298     b = state[1];
299     c = state[2];
300     d = state[3];
301     e = state[4];
302
303     static uint32_t endianness_indicator = 0x1;
304     if (((unsigned char *) &endianness_indicator)[0]) {
305         R0A_L( 0);
306         R0E_L( 1); R0D_L( 2); R0C_L( 3); R0B_L( 4); R0A_L( 5);
307         R0E_L( 6); R0D_L( 7); R0C_L( 8); R0B_L( 9); R0A_L(10);
308         R0E_L(11); R0D_L(12); R0C_L(13); R0B_L(14); R0A_L(15);
309     }
310     else {
311         R0A_B( 0);
312         R0E_B( 1); R0D_B( 2); R0C_B( 3); R0B_B( 4); R0A_B( 5);
313         R0E_B( 6); R0D_B( 7); R0C_B( 8); R0B_B( 9); R0A_B(10);
314         R0E_B(11); R0D_B(12); R0C_B(13); R0B_B(14); R0A_B(15);
315     }
316     R1E(16); R1D(17); R1C(18); R1B(19); R2A(20);
317     R2E(21); R2D(22); R2C(23); R2B(24); R2A(25);
318     R2E(26); R2D(27); R2C(28); R2B(29); R2A(30);
319     R2E(31); R2D(32); R2C(33); R2B(34); R2A(35);
320     R2E(36); R2D(37); R2C(38); R2B(39); R3A(40);
321     R3E(41); R3D(42); R3C(43); R3B(44); R3A(45);
322     R3E(46); R3D(47); R3C(48); R3B(49); R3A(50);
323     R3E(51); R3D(52); R3C(53); R3B(54); R3A(55);
324     R3E(56); R3D(57); R3C(58); R3B(59); R4A(60);
325     R4E(61); R4D(62); R4C(63); R4B(64); R4A(65);
326     R4E(66); R4D(67); R4C(68); R4B(69); R4A(70);
327     R4E(71); R4D(72); R4C(73); R4B(74); R4A(75);
328     R4E(76); R4D(77); R4C(78); R4B(79);
329
330     state[0] += a;
331     state[1] += b;
332     state[2] += c;
333     state[3] += d;
334     state[4] += e;
335 }
336
337
338 typedef struct
339 {
340     uint32_t state[5];
341     uint32_t count[2];
342     unsigned char buffer[64];
343 } SHA1Context;
344
345
346 static void SHA1_init(SHA1Context *context)
347 {
348     context->state[0] = 0x67452301;
349     context->state[1] = 0xEFCDAB89;
350     context->state[2] = 0x98BADCFE;
351     context->state[3] = 0x10325476;
352     context->state[4] = 0xC3D2E1F0;
353     context->count[0] = context->count[1] = 0;
354 }
355
356
357 static void SHA1_update(SHA1Context *context, const unsigned char *data,
358                         unsigned int len)
359 {
360     uint32_t i, j;
361
362     j = (context->count[0] >> 3) & 63;
363
364     if ((context->count[0] += len << 3) < (len << 3)) {
365         context->count[1]++;
366     }
367
368     context->count[1] += (len >> 29);
369
370     if ((j + len) > 63) {
371         memcpy(&(context->buffer[j]), data, (i = 64 - j));
372         SHA1_transform(context->state, context->buffer);
373         for ( ; (i + 63) < len; i += 64) {
374             SHA1_transform(context->state, &(data[i]));
375         }
376         j = 0;
377     }
378     else {
379         i = 0;
380     }
381
382     memcpy(&(context->buffer[j]), &(data[i]), len - i);
383 }
384
385
386 static void SHA1_final(unsigned char digest[20], SHA1Context *context)
387 {
388     uint32_t i;
389     unsigned char finalcount[8];
390
391     for (i = 0; i < 8; i++) {
392         finalcount[i] = (unsigned char)
393             ((context->count[(i >= 4 ? 0 : 1)] >>
394               ((3 - (i & 3)) * 8)) & 255);
395     }
396
397     SHA1_update(context, (unsigned char *) "\200", 1);
398
399     while ((context->count[0] & 504) != 448) {
400         SHA1_update(context, (unsigned char *) "\0", 1);
401     }
402
403     SHA1_update(context, finalcount, 8);
404
405     for (i = 0; i < 20; i++) {
406         digest[i] = (unsigned char)
407             ((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255);
408     }
409
410     memset(context->buffer, 0, 64);
411     memset(context->state, 0, 20);
412     memset(context->count, 0, 8);
413     memset(&finalcount, 0, 8);
414
415     SHA1_transform(context->state, context->buffer);
416 }
417
418
419 // HMAC-SHA-1:
420 //
421 // K - is key padded with zeros to 512 bits
422 // m - is message
423 // OPAD - 0x5c5c5c...
424 // IPAD - 0x363636...
425 //
426 // HMAC(K,m) = SHA1((K ^ OPAD) . SHA1((K ^ IPAD) . m))
427 void HMAC_SHA1(unsigned char hmac[20], const unsigned char *key, int key_len,
428                const unsigned char *message, int message_len)
429 {
430     unsigned char kopad[64], kipad[64];
431     int i;
432     
433     if (key_len > 64) {
434         key_len = 64;
435     }
436
437     for (i = 0; i < key_len; i++) {
438         kopad[i] = key[i] ^ 0x5c;
439         kipad[i] = key[i] ^ 0x36;
440     }
441
442     for ( ; i < 64; i++) {
443         kopad[i] = 0 ^ 0x5c;
444         kipad[i] = 0 ^ 0x36;
445     }
446
447     unsigned char digest[20];
448
449     SHA1Context context;
450     
451     SHA1_init(&context);
452     SHA1_update(&context, kipad, 64);
453     SHA1_update(&context, message, message_len);
454     SHA1_final(digest, &context);
455
456     SHA1_init(&context);
457     SHA1_update(&context, kopad, 64);
458     SHA1_update(&context, digest, 20);
459     SHA1_final(hmac, &context);
460 }
461
462 #define rot(x,k) (((x) << (k)) | ((x) >> (32 - (k))))
463
464 uint64_t hash(const unsigned char *k, int length)
465 {
466     uint32_t a, b, c;
467
468     a = b = c = 0xdeadbeef + ((uint32_t) length);
469
470     static uint32_t endianness_indicator = 0x1;
471     if (((unsigned char *) &endianness_indicator)[0]) {
472         while (length > 12) {
473             a += k[0];
474             a += ((uint32_t) k[1]) << 8;
475             a += ((uint32_t) k[2]) << 16;
476             a += ((uint32_t) k[3]) << 24;
477             b += k[4];
478             b += ((uint32_t) k[5]) << 8;
479             b += ((uint32_t) k[6]) << 16;
480             b += ((uint32_t) k[7]) << 24;
481             c += k[8];
482             c += ((uint32_t) k[9]) << 8;
483             c += ((uint32_t) k[10]) << 16;
484             c += ((uint32_t) k[11]) << 24;
485             a -= c; a ^= rot(c, 4);  c += b;
486             b -= a; b ^= rot(a, 6);  a += c;
487             c -= b; c ^= rot(b, 8);  b += a;
488             a -= c; a ^= rot(c, 16);  c += b;
489             b -= a; b ^= rot(a, 19);  a += c;
490             c -= b; c ^= rot(b, 4);  b += a;
491             length -= 12;
492             k += 12;
493         }
494         
495         switch(length) {
496         case 12: c += ((uint32_t) k[11]) << 24;
497         case 11: c += ((uint32_t) k[10]) << 16;
498         case 10: c += ((uint32_t) k[9]) << 8;
499         case 9 : c += k[8];
500         case 8 : b += ((uint32_t) k[7]) << 24;
501         case 7 : b += ((uint32_t) k[6]) << 16;
502         case 6 : b += ((uint32_t) k[5]) << 8;
503         case 5 : b += k[4];
504         case 4 : a += ((uint32_t) k[3]) << 24;
505         case 3 : a += ((uint32_t) k[2]) << 16;
506         case 2 : a += ((uint32_t) k[1]) << 8;
507         case 1 : a += k[0]; break;
508         case 0 : goto end;
509         }
510     }
511     else {
512         while (length > 12) {
513             a += ((uint32_t) k[0]) << 24;
514             a += ((uint32_t) k[1]) << 16;
515             a += ((uint32_t) k[2]) << 8;
516             a += ((uint32_t) k[3]);
517             b += ((uint32_t) k[4]) << 24;
518             b += ((uint32_t) k[5]) << 16;
519             b += ((uint32_t) k[6]) << 8;
520             b += ((uint32_t) k[7]);
521             c += ((uint32_t) k[8]) << 24;
522             c += ((uint32_t) k[9]) << 16;
523             c += ((uint32_t) k[10]) << 8;
524             c += ((uint32_t) k[11]);
525             a -= c; a ^= rot(c, 4);  c += b;
526             b -= a; b ^= rot(a, 6);  a += c;
527             c -= b; c ^= rot(b, 8);  b += a;
528             a -= c; a ^= rot(c, 16);  c += b;
529             b -= a; b ^= rot(a, 19);  a += c;
530             c -= b; c ^= rot(b, 4);  b += a;
531             length -= 12;
532             k += 12;
533         }
534
535         switch(length) {
536         case 12: c += k[11];
537         case 11: c += ((uint32_t) k[10]) << 8;
538         case 10: c += ((uint32_t) k[9]) << 16;
539         case 9 : c += ((uint32_t) k[8]) << 24;
540         case 8 : b += k[7];
541         case 7 : b += ((uint32_t) k[6]) << 8;
542         case 6 : b += ((uint32_t) k[5]) << 16;
543         case 5 : b += ((uint32_t) k[4]) << 24;
544         case 4 : a += k[3];
545         case 3 : a += ((uint32_t) k[2]) << 8;
546         case 2 : a += ((uint32_t) k[1]) << 16;
547         case 1 : a += ((uint32_t) k[0]) << 24; break;
548         case 0 : goto end;
549         }
550     }
551     
552     c ^= b; c -= rot(b, 14);
553     a ^= c; a -= rot(c, 11);
554     b ^= a; b -= rot(a, 25);
555     c ^= b; c -= rot(b, 16);
556     a ^= c; a -= rot(c, 4);
557     b ^= a; b -= rot(a, 14);
558     c ^= b; c -= rot(b, 24);
559
560  end:
561     return ((((uint64_t) c) << 32) | b);
562 }
563
564 int is_blank(char c)
565 {
566     return ((c == ' ') || (c == '\t'));
567 }