#ifndef DEVICE_FIDO_CTAP_GET_ASSERTION_REQUEST_H_
#define DEVICE_FIDO_CTAP_GET_ASSERTION_REQUEST_H_
#include <stdint.h>
#include <array>
#include <string>
#include <vector>
#include "base/component_export.h"
#include "base/containers/span.h"
#include "crypto/sha2.h"
#include "device/fido/cable/cable_discovery_data.h"
#include "device/fido/device_public_key_extension.h"
#include "device/fido/fido_constants.h"
#include "device/fido/large_blob.h"
#include "device/fido/pin.h"
#include "device/fido/public_key_credential_descriptor.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
namespace cbor {
class Value;
}
namespace device {
struct COMPONENT_EXPORT(DEVICE_FIDO) PRFInput {
PRFInput();
PRFInput(const PRFInput&);
PRFInput(PRFInput&&);
PRFInput& operator=(const PRFInput&);
~PRFInput();
absl::optional<std::vector<uint8_t>> credential_id;
std::array<uint8_t, 32> salt1;
absl::optional<std::array<uint8_t, 32>> salt2;
};
struct COMPONENT_EXPORT(DEVICE_FIDO) CtapGetAssertionOptions {
CtapGetAssertionOptions();
CtapGetAssertionOptions(const CtapGetAssertionOptions&);
CtapGetAssertionOptions(CtapGetAssertionOptions&&);
~CtapGetAssertionOptions();
absl::optional<pin::TokenResponse> pin_uv_auth_token;
absl::optional<pin::KeyAgreementResponse> pin_key_agreement;
std::vector<PRFInput> prf_inputs;
bool large_blob_read = false;
absl::optional<std::vector<uint8_t>> large_blob_write;
bool is_off_the_record_context = false;
};
struct COMPONENT_EXPORT(DEVICE_FIDO) CtapGetAssertionRequest {
public:
using ClientDataHash = std::array<uint8_t, kClientDataHashLength>;
struct ParseOpts {
bool reject_all_extensions = false;
};
struct HMACSecret {
HMACSecret(base::span<const uint8_t, kP256X962Length> public_key_x962,
base::span<const uint8_t> encrypted_salts,
base::span<const uint8_t> salts_auth);
HMACSecret(const HMACSecret&);
~HMACSecret();
HMACSecret& operator=(const HMACSecret&);
std::array<uint8_t, kP256X962Length> public_key_x962;
std::vector<uint8_t> encrypted_salts;
std::vector<uint8_t> salts_auth;
};
static absl::optional<CtapGetAssertionRequest> Parse(
const cbor::Value::MapValue& request_map) {
return Parse(request_map, ParseOpts());
}
static absl::optional<CtapGetAssertionRequest> Parse(
const cbor::Value::MapValue& request_map,
const ParseOpts& opts);
CtapGetAssertionRequest(std::string rp_id, std::string client_data_json);
CtapGetAssertionRequest(const CtapGetAssertionRequest& that);
CtapGetAssertionRequest(CtapGetAssertionRequest&& that);
CtapGetAssertionRequest& operator=(const CtapGetAssertionRequest& other);
CtapGetAssertionRequest& operator=(CtapGetAssertionRequest&& other);
~CtapGetAssertionRequest();
std::string rp_id;
std::string client_data_json;
std::array<uint8_t, kClientDataHashLength> client_data_hash;
UserVerificationRequirement user_verification =
UserVerificationRequirement::kDiscouraged;
bool user_presence_required = true;
std::vector<PublicKeyCredentialDescriptor> allow_list;
absl::optional<std::vector<uint8_t>> pin_auth;
absl::optional<PINUVAuthProtocol> pin_protocol;
absl::optional<std::vector<CableDiscoveryData>> cable_extension;
absl::optional<std::string> app_id;
absl::optional<std::array<uint8_t, crypto::kSHA256Length>>
alternative_application_parameter;
absl::optional<HMACSecret> hmac_secret;
bool large_blob_key = false;
bool get_cred_blob = false;
std::vector<PRFInput> prf_inputs;
bool large_blob_extension_read = false;
absl::optional<LargeBlob> large_blob_extension_write;
absl::optional<DevicePublicKeyRequest> device_public_key;
};
struct CtapGetNextAssertionRequest {};
COMPONENT_EXPORT(DEVICE_FIDO)
std::pair<CtapRequestCommand, absl::optional<cbor::Value>>
AsCTAPRequestValuePair(const CtapGetAssertionRequest&);
COMPONENT_EXPORT(DEVICE_FIDO)
std::pair<CtapRequestCommand, absl::optional<cbor::Value>>
AsCTAPRequestValuePair(const CtapGetNextAssertionRequest&);
}
#endif