[base] Make dynamic container to static span conversion explicit

This change disallows implicit conversions from dynamic containers to
static spans. This conversion can cause CHECK failures, and thus should
be done carefully. Requiring explicit construction makes it more obvious
when this happens. To aid usability, appropriate base::make_span<size_t>
overloads are added.

Bug: 877931
Change-Id: Id9f526bc57bfd30a52d14df827b0445ca087381d
Reviewed-on: https://chromium-review.googlesource.com/1189985
Reviewed-by: Ryan Sleevi <rsleevi@chromium.org>
Reviewed-by: Balazs Engedy <engedy@chromium.org>
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
Commit-Queue: Jan Wilken Dörrie <jdoerrie@chromium.org>
Cr-Commit-Position: refs/heads/master@{#586657}
ReadCTAPMakeCredentialResponse(base::span<const uint8_t> buffer) {
  if (buffer.size() <= kResponseCodeLength)
    return base::nullopt;

  base::Optional<CBOR> decoded_response =
      cbor::CBORReader::Read(buffer.subspan(1));
  if (!decoded_response || !decoded_response->is_map())
    return base::nullopt;

  const auto& decoded_map = decoded_response->GetMap();
  auto it = decoded_map.find(CBOR(1));
  if (it == decoded_map.end() || !it->second.is_string())
    return base::nullopt;
  auto format = it->second.GetString();

  it = decoded_map.find(CBOR(2));
  if (it == decoded_map.end() || !it->second.is_bytestring())
    return base::nullopt;

  auto authenticator_data =
      AuthenticatorData::DecodeAuthenticatorData(it->second.GetBytestring());
  if (!authenticator_data)
    return base::nullopt;

  it = decoded_map.find(CBOR(3));
  if (it == decoded_map.end() || !it->second.is_map())
    return base::nullopt;

  return AuthenticatorMakeCredentialResponse(
      AttestationObject(std::move(*authenticator_data),
                        std::make_unique<OpaqueAttestationStatement>(
                            format, it->second.Clone())));
}

ReadCTAPMakeCredentialResponse(base::span<const uint8_t> buffer) {
  if (buffer.size() <= kResponseCodeLength)
    return base::nullopt;

  base::Optional<CBOR> decoded_response =
      cbor::CBORReader::Read(buffer.subspan(1));
  if (!decoded_response || !decoded_response->is_map())
    return base::nullopt;

  const auto& decoded_map = decoded_response->GetMap();
  auto it = decoded_map.find(CBOR(1));
  if (it == decoded_map.end() || !it->second.is_string())
    return base::nullopt;
  auto format = it->second.GetString();

  it = decoded_map.find(CBOR(2));
  if (it == decoded_map.end() || !it->second.is_bytestring())
    return base::nullopt;

  auto authenticator_data =
      AuthenticatorData::DecodeAuthenticatorData(it->second.GetBytestring());
  if (!authenticator_data)
    return base::nullopt;

  it = decoded_map.find(CBOR(3));
  if (it == decoded_map.end() || !it->second.is_map())
    return base::nullopt;

  return AuthenticatorMakeCredentialResponse(
      AttestationObject(std::move(*authenticator_data),
                        std::make_unique<OpaqueAttestationStatement>(
                            format, it->second.Clone())));
}
