GetObjectOutcome CryptoModule::GetObjectSecurely()

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