diff -r e59a989d890d -r 060a8cda7f62 dav/sync.c --- a/dav/sync.c Thu Mar 28 11:19:13 2019 +0100 +++ b/dav/sync.c Thu Mar 28 11:54:27 2019 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2018 Olaf Wintermann. All rights reserved. + * Copyright 2019 Olaf Wintermann. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -517,7 +517,7 @@ } int ret = 0; - DavResource *ls = dav_query(sn, "select D:getetag,idav:status,idav:tags,idav:finfo,idav:xattributes from / with depth = infinity"); + DavResource *ls = dav_query(sn, "select D:getetag,idav:status,idav:tags,idav:finfo,idav:xattributes,idav:content-hash from / with depth = infinity"); if(!ls) { print_resource_error(sn, "/"); if(locked) { @@ -2055,7 +2055,7 @@ int ret = 0; if(err == 0) { char *etag = dav_get_string_property(remote, "D:getetag"); - char *hash = dav_get_string_property(remote, "idav:content-hash"); + char *hash = sync_get_content_hash(remote); if(hash || res->hash) { if(!nullstrcmp(hash, res->hash)) { ret = 1; @@ -2810,9 +2810,8 @@ // set content-hash char content_hash[DAV_SHA256_DIGEST_LENGTH]; dav_hash_final(sha, content_hash); - char *hash_hex = util_hexstr(content_hash, DAV_SHA256_DIGEST_LENGTH); - dav_set_string_property_ns(res, DAV_NS, "content-hash", hash_hex); - local->hash = hash_hex; + sync_set_content_hash(res, content_hash); + local->hash = util_hexstr(content_hash, DAV_SHA256_DIGEST_LENGTH); // get etags from uploaded resources // also delete everything, that is not part of the file @@ -4134,3 +4133,46 @@ } } +char* sync_get_content_hash(DavResource *res) { + uint32_t flags = res->session->flags; + if((flags & DAV_SESSION_ENCRYPT_CONTENT) == DAV_SESSION_ENCRYPT_CONTENT) { + char *enc_hash = dav_get_string_property_ns(res, DAV_NS, "crypto-hash"); + char *keyname = dav_get_string_property_ns(res, DAV_NS, "crypto-key"); + if(enc_hash && keyname) { + DavKey *key = dav_context_get_key(res->session->context, keyname); + if(!key) { + return NULL; + } + + size_t len = 0; + char *dec_hash = aes_decrypt(enc_hash, &len, key); + if(!dec_hash) { + return NULL; + } + + char *hex_hash = util_hexstr((unsigned char*)dec_hash, len); + free(dec_hash); + return hex_hash; + } + } else { + return dav_get_string_property_ns(res, DAV_NS, "content-hash"); + } + return NULL; +} + +void sync_set_content_hash(DavResource *res, const char *hashdata) { + uint32_t flags = res->session->flags; + if((flags & DAV_SESSION_ENCRYPT_CONTENT) == DAV_SESSION_ENCRYPT_CONTENT) { + if(res->session->key) { + char *enc_hash = aes_encrypt(hashdata, DAV_SHA256_DIGEST_LENGTH, res->session->key); + if(enc_hash) { + dav_set_string_property_ns(res, DAV_NS, "crypto-hash", enc_hash); + free(enc_hash); + } + } + } else { + char *hex_hash = util_hexstr((const unsigned char*)hashdata, DAV_SHA256_DIGEST_LENGTH); + dav_set_string_property_ns(res, DAV_NS, "content-hash", hex_hash); + free(hex_hash); + } +}