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); |