Commit 6bc69af1 authored by Adam Langley's avatar Adam Langley Committed by Commit Bot

device/fido: check CBOR types before access.

(Accessors like |GetUnsigned| will crash if the type of the value is
anything unexpected.)

Change-Id: Ic7c5e0971b00e2c566d32b18efc620780ee7c96d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1636649
Commit-Queue: Adam Langley <agl@chromium.org>
Reviewed-by: default avatarKim Paulhamus <kpaulhamus@chromium.org>
Cr-Commit-Position: refs/heads/master@{#666293}
parent 9184177e
...@@ -47,6 +47,9 @@ base::Optional<BioEnrollmentResponse> BioEnrollmentResponse::Parse( ...@@ -47,6 +47,9 @@ base::Optional<BioEnrollmentResponse> BioEnrollmentResponse::Parse(
auto it = response_map.find( auto it = response_map.find(
cbor::Value(static_cast<int>(BioEnrollmentResponseKey::kModality))); cbor::Value(static_cast<int>(BioEnrollmentResponseKey::kModality)));
if (it != response_map.end()) { if (it != response_map.end()) {
if (!it->second.is_unsigned()) {
return base::nullopt;
}
response.modality = response.modality =
static_cast<BioEnrollmentModality>(it->second.GetUnsigned()); static_cast<BioEnrollmentModality>(it->second.GetUnsigned());
} }
...@@ -55,6 +58,9 @@ base::Optional<BioEnrollmentResponse> BioEnrollmentResponse::Parse( ...@@ -55,6 +58,9 @@ base::Optional<BioEnrollmentResponse> BioEnrollmentResponse::Parse(
it = response_map.find(cbor::Value( it = response_map.find(cbor::Value(
static_cast<int>(BioEnrollmentResponseKey::kFingerprintKind))); static_cast<int>(BioEnrollmentResponseKey::kFingerprintKind)));
if (it != response_map.end()) { if (it != response_map.end()) {
if (!it->second.is_unsigned()) {
return base::nullopt;
}
response.fingerprint_kind = response.fingerprint_kind =
static_cast<BioEnrollmentFingerprintKind>(it->second.GetUnsigned()); static_cast<BioEnrollmentFingerprintKind>(it->second.GetUnsigned());
} }
...@@ -63,6 +69,9 @@ base::Optional<BioEnrollmentResponse> BioEnrollmentResponse::Parse( ...@@ -63,6 +69,9 @@ base::Optional<BioEnrollmentResponse> BioEnrollmentResponse::Parse(
it = response_map.find(cbor::Value(static_cast<int>( it = response_map.find(cbor::Value(static_cast<int>(
BioEnrollmentResponseKey::kMaxCaptureSamplesRequiredForEnroll))); BioEnrollmentResponseKey::kMaxCaptureSamplesRequiredForEnroll)));
if (it != response_map.end()) { if (it != response_map.end()) {
if (!it->second.is_unsigned()) {
return base::nullopt;
}
response.max_samples_for_enroll = it->second.GetUnsigned(); response.max_samples_for_enroll = it->second.GetUnsigned();
} }
......
...@@ -1334,7 +1334,14 @@ CtapDeviceResponseCode VirtualCtap2Device::OnBioEnrollment( ...@@ -1334,7 +1334,14 @@ CtapDeviceResponseCode VirtualCtap2Device::OnBioEnrollment(
// Check for the get-modality command. // Check for the get-modality command.
auto it = request_map.find( auto it = request_map.find(
cbor::Value(static_cast<int>(BioEnrollmentRequestKey::kGetModality))); cbor::Value(static_cast<int>(BioEnrollmentRequestKey::kGetModality)));
if (it != request_map.end() && it->second.GetBool()) { if (it != request_map.end()) {
if (!it->second.is_bool()) {
return CtapDeviceResponseCode::kCtap2ErrCBORUnexpectedType;
}
if (!it->second.GetBool()) {
// This value is optional so sending |false| is prohibited by the spec.
return CtapDeviceResponseCode::kCtap2ErrInvalidOption;
}
response_map.emplace(static_cast<int>(BioEnrollmentResponseKey::kModality), response_map.emplace(static_cast<int>(BioEnrollmentResponseKey::kModality),
static_cast<int>(BioEnrollmentModality::kFingerprint)); static_cast<int>(BioEnrollmentModality::kFingerprint));
*response = *response =
...@@ -1345,11 +1352,20 @@ CtapDeviceResponseCode VirtualCtap2Device::OnBioEnrollment( ...@@ -1345,11 +1352,20 @@ CtapDeviceResponseCode VirtualCtap2Device::OnBioEnrollment(
// Check for the get-sensor-info command. // Check for the get-sensor-info command.
it = request_map.find( it = request_map.find(
cbor::Value(static_cast<int>(BioEnrollmentRequestKey::kSubCommand))); cbor::Value(static_cast<int>(BioEnrollmentRequestKey::kSubCommand)));
if (it != request_map.end() && if (it == request_map.end()) {
it->second.GetUnsigned() == // Could not find a valid command, so return an error.
static_cast<int>( NOTREACHED();
BioEnrollmentSubCommand::kGetFingerprintSensorInfo)) { return CtapDeviceResponseCode::kCtap2ErrInvalidOption;
response_map.emplace(static_cast<int>(BioEnrollmentResponseKey::kModality), }
if (!it->second.is_unsigned()) {
return CtapDeviceResponseCode::kCtap2ErrCBORUnexpectedType;
}
switch (static_cast<BioEnrollmentSubCommand>(it->second.GetUnsigned())) {
case BioEnrollmentSubCommand::kGetFingerprintSensorInfo:
response_map.emplace(
static_cast<int>(BioEnrollmentResponseKey::kModality),
static_cast<int>(BioEnrollmentModality::kFingerprint)); static_cast<int>(BioEnrollmentModality::kFingerprint));
response_map.emplace( response_map.emplace(
...@@ -1363,17 +1379,12 @@ CtapDeviceResponseCode VirtualCtap2Device::OnBioEnrollment( ...@@ -1363,17 +1379,12 @@ CtapDeviceResponseCode VirtualCtap2Device::OnBioEnrollment(
*response = *response =
cbor::Writer::Write(cbor::Value(std::move(response_map))).value(); cbor::Writer::Write(cbor::Value(std::move(response_map))).value();
return CtapDeviceResponseCode::kSuccess; return CtapDeviceResponseCode::kSuccess;
}
// Handle all other commands as if they were unsupported (will change when default:
// support is added). // Handle all other commands as if they were unsupported (will change
if (it != request_map.end()) { // when support is added).
return CtapDeviceResponseCode::kCtap2ErrUnsupportedOption; return CtapDeviceResponseCode::kCtap2ErrUnsupportedOption;
} }
// Could not find a valid command, so return an error.
NOTREACHED();
return CtapDeviceResponseCode::kCtap2ErrInvalidOption;
} }
void VirtualCtap2Device::InitPendingRPs() { void VirtualCtap2Device::InitPendingRPs() {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment