absl::Status GetAttributeValue()

in kmsp11/main/bridge.cc [335:380]


absl::Status GetAttributeValue(CK_SESSION_HANDLE hSession,
                               CK_OBJECT_HANDLE hObject,
                               CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) {
  ASSIGN_OR_RETURN(std::shared_ptr<Session> session, GetSession(hSession));
  ASSIGN_OR_RETURN(std::shared_ptr<Object> object,
                   session->token()->GetObject(hObject));
  if (!pTemplate) {
    return NullArgumentError("pTemplate", SOURCE_LOCATION);
  }

  absl::Status result = absl::OkStatus();
  for (CK_ATTRIBUTE& attr : absl::MakeSpan(pTemplate, ulCount)) {
    absl::StatusOr<std::string_view> value =
        object->attributes().Value(attr.type);

    // C_GetAttributeValue cases 1 and 2
    if (!value.ok()) {
      result = value.status();
      attr.ulValueLen = CK_UNAVAILABLE_INFORMATION;
      continue;
    }

    // C_GetAttributeValue case 3
    if (!attr.pValue) {
      attr.ulValueLen = value->size();
      continue;
    }

    // C_GetAttributeValue case 4
    if (attr.ulValueLen >= value->size()) {
      std::copy(value->begin(), value->end(), static_cast<char*>(attr.pValue));
      attr.ulValueLen = value->size();
      continue;
    }

    // C_GetAttributeValue case 5
    attr.ulValueLen = CK_UNAVAILABLE_INFORMATION;
    result = OutOfRangeError(
        absl::StrFormat(
            "attribute %#X is of length %d, received buffer of length %d",
            attr.type, value->size(), attr.ulValueLen),
        SOURCE_LOCATION);
  }

  return result;
}