in sdk/src/encryption/CryptoModule.cc [77:133]
GetObjectOutcome CryptoModule::GetObjectSecurely(const std::shared_ptr<OssClientImpl>& client, const GetObjectRequest& request, const ObjectMetaData& meta)
{
GetObjectRequest getRequest(request);
ContentCryptoMaterial material;
readMetaData(material, meta);
initDecryptionCipher(material);
if (material.CipherName() != cipher_->Name()) {
std::stringstream ss;
ss << "Cipher name is not support, " <<
"expect " << cipher_->Name() << ", "
"got " << material.CipherName() << ".";
return GetObjectOutcome(OssError("EncryptionClientError", ss.str()));
}
auto ret = encryptionMaterials_->DecryptCEK(material);
CHECK_FUNC_RET(GetObjectOutcome, DecryptCEK, ret);
//range
auto iv = material.ContentIV();
auto range = request.Range();
int64_t skipCnt = 0;
int64_t blkSize = static_cast<int64_t>(cipher_->BlockSize());
if (range.first > 0) {
auto blockOfNum = range.first / blkSize;
auto newBegin = blockOfNum * blkSize;
skipCnt = range.first % blkSize;
getRequest.setRange(newBegin, range.second);
iv = cipher_->IncCTRCounter(iv, static_cast<uint64_t>(blockOfNum));
}
//ua
getRequest.setUserAgent(getUserAgent(client->configuration().userAgent));
std::shared_ptr<CryptoStreamBuf> cryptoStream = nullptr;
std::shared_ptr<std::iostream> userContent = nullptr;
getRequest.setResponseStreamFactory([&]() {
auto content = request.ResponseStreamFactory()();
cryptoStream = std::make_shared<CryptoStreamBuf>(*content, cipher_, material.ContentKey(), iv, static_cast<int>(skipCnt));
userContent = content;
return content;
}
);
auto outcome = client->GetObject(getRequest);
if (skipCnt > 0 && outcome.isSuccess()) {
ObjectMetaData ometa = outcome.result().Metadata();
auto len = ometa.ContentLength();
ometa.setContentLength(len - skipCnt);
outcome.result().setMetaData(ometa);
}
cryptoStream = nullptr;
userContent = nullptr;
return outcome;
}