kmscng/util/status_utils.cc (63 lines of code) (raw):

// Copyright 2023 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include "kmscng/util/status_utils.h" #include <windows.h> #include <cstring> #include <optional> #include <string> #include "absl/status/status_payload_printer.h" #include "absl/strings/cord.h" #include "absl/strings/escaping.h" #include "absl/strings/str_format.h" #include "common/status_details.pb.h" #include "glog/logging.h" namespace cloud_kms::kmscng { namespace { // The URL we'll use for storing a custom payload in the status. // Notes on the naming convention are at // https://github.com/abseil/abseil-cpp/blob/bf6166a635ab57fe0559b00dcd3ff09a8c42de2e/absl/status/status.h#L149 constexpr std::string_view kTypeUrl = "type.googleapis.com/kmscng.StatusDetails"; SECURITY_STATUS ExtractSsFromCord(const absl::Cord& cord) { std::string payload(cord); StatusDetails details; if (!details.ParseFromString(payload)) { // It doesn't really make sense to return an error status from a function // that is itself processing an error status. Log a warning instead. LOG(WARNING) << "status payload of type " << kTypeUrl << " with payload '" << absl::BytesToHexString(payload) << "' could not be parsed as a StatusDetails"; } return details.rv(); } std::optional<std::string> PrintPayload(std::string_view type_url, const absl::Cord& content) { if (type_url != kTypeUrl) { return std::nullopt; } return absl::StrFormat("SECURITY_STATUS=%#x", ExtractSsFromCord(content)); } } // namespace void SetErrorSs(absl::Status& status, SECURITY_STATUS ss) { static const bool kPayloadPrinterRegistered = [] { absl::status_internal::SetStatusPayloadPrinter(&PrintPayload); return true; }(); CHECK(kPayloadPrinterRegistered); CHECK(!status.ok()) << "attempting to set ss=" << ss << " for status OK"; CHECK(ss != ERROR_SUCCESS) << "attempting to set ss=0 for status " << status; StatusDetails details; details.set_rv(ss); status.SetPayload(kTypeUrl, absl::Cord(details.SerializeAsString())); } SECURITY_STATUS GetErrorSs(const absl::Status& status) { if (status.ok()) { return ERROR_SUCCESS; } std::optional<absl::Cord> payload = status.GetPayload(kTypeUrl); if (!payload.has_value()) { return kDefaultErrorStatus; } SECURITY_STATUS ss = ExtractSsFromCord(*payload); if (ss == ERROR_SUCCESS) { LOG(WARNING) << "recovered status details has ss=ERROR_SUCCESS; falling back to " "default error code"; return kDefaultErrorStatus; } return ss; } } // namespace cloud_kms::kmscng