return 0;
}
+int RGWGetObj_BlockDecrypt::process(bufferlist& in, size_t part_ofs, size_t size)
+{
+ bufferlist data;
+ if (!crypt->decrypt(in, 0, size, data, part_ofs)) {
+ return -ERR_INTERNAL_ERROR;
+ }
+ off_t send_size = size - enc_begin_skip;
+ if (ofs + enc_begin_skip + send_size > end + 1) {
+ send_size = end + 1 - ofs - enc_begin_skip;
+ }
+ int res = next->handle_data(data, enc_begin_skip, send_size);
+ enc_begin_skip = 0;
+ ofs += size;
+ in.splice(0, size);
+ return res;
+}
int RGWGetObj_BlockDecrypt::handle_data(bufferlist& bl, off_t bl_ofs, off_t bl_len) {
- int res = 0;
ldout(cct, 25) << "Decrypt " << bl_len << " bytes" << dendl;
+ bl.copy(bl_ofs, bl_len, cache);
+
+ int res = 0;
size_t part_ofs = ofs;
- size_t i = 0;
- while (i<parts_len.size() && (part_ofs >= parts_len[i])) {
- part_ofs -= parts_len[i];
- i++;
+ for (size_t part : parts_len) {
+ if (part_ofs >= part) {
+ part_ofs -= part;
+ } else if (part_ofs + cache.length() >= part) {
+ // flush data up to part boundaries, aligned or not
+ res = process(cache, part_ofs, part - part_ofs);
+ if (res < 0) {
+ return res;
+ }
+ part_ofs = 0;
+ } else {
+ break;
+ }
}
- bl.copy(bl_ofs, bl_len, cache);
+ // write up to block boundaries, aligned only
off_t aligned_size = cache.length() & ~(block_size - 1);
if (aligned_size > 0) {
- bufferlist data;
- if (! crypt->decrypt(cache, 0, aligned_size, data, part_ofs) ) {
- return -ERR_INTERNAL_ERROR;
- }
- off_t send_size = aligned_size - enc_begin_skip;
- if (ofs + enc_begin_skip + send_size > end + 1) {
- send_size = end + 1 - ofs - enc_begin_skip;
- }
- res = next->handle_data(data, enc_begin_skip, send_size);
- enc_begin_skip = 0;
- ofs += aligned_size;
- cache.splice(0, aligned_size);
+ res = process(cache, part_ofs, aligned_size);
}
return res;
}
* flush remainder of data to output
*/
int RGWGetObj_BlockDecrypt::flush() {
+ ldout(cct, 25) << "Decrypt flushing " << cache.length() << " bytes" << dendl;
int res = 0;
size_t part_ofs = ofs;
- size_t i = 0;
- while (i<parts_len.size() && (part_ofs > parts_len[i])) {
- part_ofs -= parts_len[i];
- i++;
+ for (size_t part : parts_len) {
+ if (part_ofs >= part) {
+ part_ofs -= part;
+ } else if (part_ofs + cache.length() >= part) {
+ // flush data up to part boundaries, aligned or not
+ res = process(cache, part_ofs, part - part_ofs);
+ if (res < 0) {
+ return res;
+ }
+ part_ofs = 0;
+ } else {
+ break;
+ }
}
+ // flush up to block boundaries, aligned or not
if (cache.length() > 0) {
- bufferlist data;
- if (! crypt->decrypt(cache, 0, cache.length(), data, part_ofs) ) {
- return -ERR_INTERNAL_ERROR;
- }
- off_t send_size = cache.length() - enc_begin_skip;
- if (ofs + enc_begin_skip + send_size > end + 1) {
- send_size = end + 1 - ofs - enc_begin_skip;
- }
- res = next->handle_data(data, enc_begin_skip, send_size);
- enc_begin_skip = 0;
- ofs += send_size;
+ res = process(cache, part_ofs, cache.length());
}
return res;
}
res = rgw_s3_prepare_decrypt(s, attrs, &block_crypt, crypt_http_responses);
if (res == 0) {
if (block_crypt != nullptr) {
- auto f = std::unique_ptr<RGWGetObj_BlockDecrypt>(new RGWGetObj_BlockDecrypt(s->cct, cb, std::move(block_crypt)));
- //RGWGetObj_BlockDecrypt* f = new RGWGetObj_BlockDecrypt(s->cct, cb, std::move(block_crypt));
- if (f != nullptr) {
- if (manifest_bl != nullptr) {
- res = f->read_manifest(*manifest_bl);
- if (res == 0) {
- *filter = std::move(f);
- }
+ auto f = std::make_unique<RGWGetObj_BlockDecrypt>(s->cct, cb, std::move(block_crypt));
+ if (manifest_bl != nullptr) {
+ res = f->read_manifest(*manifest_bl);
+ if (res == 0) {
+ *filter = std::move(f);
}
}
}