653 ucx_buffer_free(rqbuf); |
653 ucx_buffer_free(rqbuf); |
654 ucx_mempool_destroy(mp); |
654 ucx_mempool_destroy(mp); |
655 return ret; |
655 return ret; |
656 } |
656 } |
657 |
657 |
|
658 |
|
659 /* |
|
660 * read wrapper with integrated hashing |
|
661 */ |
|
662 |
|
663 typedef struct { |
|
664 DAV_SHA_CTX *sha; |
|
665 void *stream; |
|
666 dav_read_func read; |
|
667 dav_seek_func seek; |
|
668 int error; |
|
669 } HashStream; |
|
670 |
|
671 static void init_hash_stream(HashStream *hstr, void *stream, dav_read_func readfn, dav_seek_func seekfn) { |
|
672 hstr->sha = NULL; |
|
673 hstr->stream = stream; |
|
674 hstr->read = readfn; |
|
675 hstr->seek = seekfn; |
|
676 hstr->error = 0; |
|
677 } |
|
678 |
|
679 static size_t dav_read_h(void *buf, size_t size, size_t nelm, void *stream) { |
|
680 HashStream *s = stream; |
|
681 if(!s->sha) { |
|
682 s->sha = dav_hash_init(); |
|
683 } |
|
684 |
|
685 size_t r = s->read(buf, size, nelm, s->stream); |
|
686 dav_hash_update(s->sha, buf, r); |
|
687 return r; |
|
688 } |
|
689 |
|
690 static int dav_seek_h(void *stream, long offset, int whence) { |
|
691 HashStream *s = stream; |
|
692 if(offset == 0 && whence == SEEK_SET) { |
|
693 char buf[DAV_SHA256_DIGEST_LENGTH]; |
|
694 dav_hash_final(s->sha, buf); |
|
695 s->sha = NULL; |
|
696 } else { |
|
697 s->error = 1; |
|
698 } |
|
699 return s->seek(s->stream, offset, whence); |
|
700 } |
|
701 |
|
702 |
658 int dav_store(DavResource *res) { |
703 int dav_store(DavResource *res) { |
659 DavSession *sn = res->session; |
704 DavSession *sn = res->session; |
660 DavResourceData *data = res->data; |
705 DavResourceData *data = res->data; |
661 |
706 |
662 util_set_url(sn, dav_resource_get_href(res)); |
707 util_set_url(sn, dav_resource_get_href(res)); |
696 (dav_read_func)aes_read, |
741 (dav_read_func)aes_read, |
697 (dav_seek_func)aes_encrypter_reset, |
742 (dav_seek_func)aes_encrypter_reset, |
698 0); |
743 0); |
699 |
744 |
700 // get sha256 hash |
745 // get sha256 hash |
701 unsigned char sha[DAV_SHA256_DIGEST_LENGTH]; |
746 dav_get_hash(&enc->sha256, (unsigned char*)data->hash); |
702 dav_get_hash(&enc->sha256, sha); |
747 char *enc_hash = aes_encrypt(data->hash, DAV_SHA256_DIGEST_LENGTH, sn->key); |
703 char *enc_hash = aes_encrypt((char*)sha, DAV_SHA256_DIGEST_LENGTH, sn->key); |
|
704 |
748 |
705 aes_encrypter_close(enc); |
749 aes_encrypter_close(enc); |
706 if(buf) { |
750 if(buf) { |
707 ucx_buffer_free(buf); |
751 ucx_buffer_free(buf); |
708 } |
752 } |
713 free(enc_hash); |
757 free(enc_hash); |
714 return 1; |
758 return 1; |
715 } |
759 } |
716 resource_add_string_property(res, DAV_NS, "crypto-hash", enc_hash); |
760 resource_add_string_property(res, DAV_NS, "crypto-hash", enc_hash); |
717 free(enc_hash); |
761 free(enc_hash); |
|
762 } else if((sn->flags & DAV_SESSION_STORE_HASH) == DAV_SESSION_STORE_HASH) { |
|
763 HashStream hstr; |
|
764 UcxBuffer *iobuf = NULL; |
|
765 if(!data->read) { |
|
766 iobuf = ucx_buffer_new(data->content, data->length, 0); |
|
767 iobuf->size = data->length; |
|
768 init_hash_stream( |
|
769 &hstr, |
|
770 iobuf, |
|
771 (dav_read_func)ucx_buffer_read, |
|
772 (dav_seek_func)ucx_buffer_seek); |
|
773 } else { |
|
774 init_hash_stream( |
|
775 &hstr, |
|
776 data->content, |
|
777 data->read, |
|
778 data->seek); |
|
779 } |
|
780 |
|
781 ret = do_put_request( |
|
782 sn, |
|
783 locktoken, |
|
784 TRUE, |
|
785 &hstr, |
|
786 dav_read_h, |
|
787 (dav_seek_func)dav_seek_h, |
|
788 data->length); |
|
789 |
|
790 if(hstr.sha) { |
|
791 dav_hash_final(hstr.sha, (unsigned char*)data->hash); |
|
792 char *hash = util_hexstr(data->hash, 32); |
|
793 dav_set_string_property_ns(res, DAV_NS, "content-hash", hash); |
|
794 free(hash); |
|
795 } |
718 } else { |
796 } else { |
719 ret = do_put_request( |
797 ret = do_put_request( |
720 sn, |
798 sn, |
721 locktoken, |
799 locktoken, |
722 TRUE, |
800 TRUE, |