libidav/utils.c

changeset 344
72791e299d64
parent 337
d7bda914d120
child 349
0b4ecadaf3f9
equal deleted inserted replaced
338:c7f3fe4abdb2 344:72791e299d64
464 char* util_base64decode(char *in) { 464 char* util_base64decode(char *in) {
465 int len = 0; 465 int len = 0;
466 return util_base64decode_len(in, &len); 466 return util_base64decode_len(in, &len);
467 } 467 }
468 468
469 #define WHITESPACE 64
470 #define EQUALS 65
471 #define INVALID 66
472 static char b64dectable[] = {
473 66,66,66,66,66,66,66,66,66,66,64,66,66,66,66,66,66,66,66,66,66,66,66,66,66,
474 66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,62,66,66,66,63,52,53,
475 54,55,56,57,58,59,60,61,66,66,66,65,66,66,66, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
476 10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,66,66,66,66,66,66,26,27,28,
477 29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,66,66,
478 66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,
479 66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,
480 66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,
481 66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,
482 66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,
483 66,66,66,66,66,66
484 };
469 char* util_base64decode_len(char* in, int *outlen) { 485 char* util_base64decode_len(char* in, int *outlen) {
470 size_t len = strlen(in); 486 /* code is mostly from wikibooks */
471 char *out = calloc(1, len); 487
472 488 size_t inlen = strlen(in);
473 BIO *b = BIO_new_mem_buf(in, len); 489 size_t bufsize = (inlen*3) / 4;
474 BIO *d = BIO_new(BIO_f_base64()); 490 char *outbuf = malloc(bufsize+1);
475 BIO_set_flags(d, BIO_FLAGS_BASE64_NO_NL); 491 *outlen = -1;
476 b = BIO_push(d, b); 492
477 493 unsigned char *out = outbuf;
478 *outlen = BIO_read(b, out, len); 494
479 BIO_free_all(b); 495 char *end = in + inlen;
480 496 char iter = 0;
481 return out; 497 uint32_t buf = 0;
482 } 498 size_t len = 0;
483 499
484 char* util_base64encode(char *in, size_t len) { 500 while (in < end) {
485 BIO *b; 501 unsigned char c = b64dectable[*in++];
486 BIO *e; 502
487 BUF_MEM *mem; 503 switch (c) {
488 504 case WHITESPACE: continue; /* skip whitespace */
489 e = BIO_new(BIO_f_base64()); 505 case INVALID: {
490 b = BIO_new(BIO_s_mem()); 506 /* invalid input */
491 BIO_set_flags(e, BIO_FLAGS_BASE64_NO_NL); 507 outbuf[0] = 0;
492 508 return outbuf;
493 e = BIO_push(e, b); 509 }
494 BIO_write(e, in, len); 510 case EQUALS: {
495 BIO_flush(e); 511 /* pad character, end of data */
496 512 in = end;
497 BIO_get_mem_ptr(e, &mem); 513 continue;
498 char *out = malloc(mem->length + 1); 514 }
499 memcpy(out, mem->data, mem->length); 515 default: {
500 out[mem->length] = '\0'; 516 buf = buf << 6 | c;
501 517 iter++; // increment the number of iteration
502 BIO_free_all(e); 518 /* If the buffer is full, split it into bytes */
503 519 if (iter == 4) {
520 if ((len += 3) > bufsize) {
521 /* buffer overflow */
522 outbuf[0] = 0;
523 return outbuf;
524 }
525 *(out++) = (buf >> 16) & 255;
526 *(out++) = (buf >> 8) & 255;
527 *(out++) = buf & 255;
528 buf = 0; iter = 0;
529
530 }
531 }
532 }
533 }
534
535 if (iter == 3) {
536 if ((len += 2) > bufsize) {
537 /* buffer overflow */
538 outbuf[0] = 0;
539 return outbuf;
540 }
541 *(out++) = (buf >> 10) & 255;
542 *(out++) = (buf >> 2) & 255;
543 }
544 else if (iter == 2) {
545 if (++len > bufsize) {
546 /* buffer overflow */
547 outbuf[0] = 0;
548 return outbuf;
549 }
550 *(out++) = (buf >> 4) & 255;
551 }
552
553 *outlen = len; /* modify to reflect the actual output size */
554 outbuf[len] = 0;
555 return outbuf;
556 }
557
558
559 static char* b64enctable = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
560 char* util_base64encode(char *in, size_t len) {
561 // calculate length of base64 output and create buffer
562 size_t outlen = 4 * ((len + 2) / 3);
563 int pad = len % 3;
564
565 char *out = malloc(outlen + 1);
566 out[outlen] = 0;
567 size_t pos = 0;
568
569 // encode blocks of 3 bytes
570 size_t i;
571 size_t blockend = len - pad;
572 for(i=0;i<blockend;i++) {
573 unsigned char b1 = in[i++];
574 unsigned char b2 = in[i++];
575 unsigned char b3 = in[i];
576 uint32_t inb = b1 << 16 | (b2 << 8) | b3;
577 out[pos++] = b64enctable[(inb >> 18) & 63];
578 out[pos++] = b64enctable[(inb >> 12) & 63];
579 out[pos++] = b64enctable[(inb >> 6) & 63];
580 out[pos++] = b64enctable[(inb) & 63];
581 }
582
583 // encode last bytes
584 if(pad > 0) {
585 char p[3] = {0, 0, 0};
586 for(int j=0;i<len;i++) {
587 p[j++] = in[i];
588 }
589 unsigned char b1 = p[0];
590 unsigned char b2 = p[1];
591 unsigned char b3 = p[2];
592 uint32_t inb = (b1 << 16) | (b2 << 8) | b3;
593 out[pos++] = b64enctable[(inb >> 18) & 63];
594 out[pos++] = b64enctable[(inb >> 12) & 63];
595 out[pos++] = b64enctable[(inb >> 6) & 63];
596 out[pos++] = b64enctable[(inb) & 63];
597 for(int k=outlen-1;k>=outlen-(3-pad);k--) {
598 out[k] = '=';
599 }
600 }
601
504 return out; 602 return out;
505 } 603 }
506 604
507 char* util_encrypt_str(DavSession *sn, char *str, char *key) { 605 char* util_encrypt_str(DavSession *sn, char *str, char *key) {
508 DavKey *k = dav_context_get_key(sn->context, key); 606 DavKey *k = dav_context_get_key(sn->context, key);

mercurial