authenticator_get_assertion_response.cc 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. // Copyright 2018 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "device/fido/authenticator_get_assertion_response.h"
  5. #include <utility>
  6. #include "components/cbor/values.h"
  7. #include "components/cbor/writer.h"
  8. #include "components/device_event_log/device_event_log.h"
  9. #include "device/fido/authenticator_data.h"
  10. #include "device/fido/fido_parsing_utils.h"
  11. #include "third_party/abseil-cpp/absl/types/optional.h"
  12. #include "third_party/boringssl/src/include/openssl/ecdsa.h"
  13. namespace device {
  14. namespace {
  15. constexpr size_t kFlagIndex = 0;
  16. constexpr size_t kFlagLength = 1;
  17. constexpr size_t kCounterIndex = 1;
  18. constexpr size_t kCounterLength = 4;
  19. constexpr size_t kSignatureIndex = 5;
  20. } // namespace
  21. // static
  22. absl::optional<AuthenticatorGetAssertionResponse>
  23. AuthenticatorGetAssertionResponse::CreateFromU2fSignResponse(
  24. base::span<const uint8_t, kRpIdHashLength> relying_party_id_hash,
  25. base::span<const uint8_t> u2f_data,
  26. base::span<const uint8_t> key_handle) {
  27. if (u2f_data.size() <= kSignatureIndex)
  28. return absl::nullopt;
  29. if (key_handle.empty())
  30. return absl::nullopt;
  31. auto flags = u2f_data.subspan<kFlagIndex, kFlagLength>()[0];
  32. if (flags &
  33. (static_cast<uint8_t>(AuthenticatorData::Flag::kExtensionDataIncluded) |
  34. static_cast<uint8_t>(AuthenticatorData::Flag::kAttestation))) {
  35. // U2F responses cannot assert CTAP2 features.
  36. return absl::nullopt;
  37. }
  38. auto counter = u2f_data.subspan<kCounterIndex, kCounterLength>();
  39. AuthenticatorData authenticator_data(relying_party_id_hash, flags, counter,
  40. absl::nullopt);
  41. auto signature =
  42. fido_parsing_utils::Materialize(u2f_data.subspan(kSignatureIndex));
  43. bssl::UniquePtr<ECDSA_SIG> parsed_sig(
  44. ECDSA_SIG_from_bytes(signature.data(), signature.size()));
  45. if (!parsed_sig) {
  46. FIDO_LOG(ERROR)
  47. << "Rejecting U2F assertion response with invalid signature";
  48. return absl::nullopt;
  49. }
  50. AuthenticatorGetAssertionResponse response(std::move(authenticator_data),
  51. std::move(signature));
  52. response.credential = PublicKeyCredentialDescriptor(
  53. CredentialType::kPublicKey, fido_parsing_utils::Materialize(key_handle));
  54. return std::move(response);
  55. }
  56. AuthenticatorGetAssertionResponse::AuthenticatorGetAssertionResponse(
  57. AuthenticatorData authenticator_data,
  58. std::vector<uint8_t> signature)
  59. : authenticator_data(std::move(authenticator_data)),
  60. signature(std::move(signature)) {}
  61. AuthenticatorGetAssertionResponse::AuthenticatorGetAssertionResponse(
  62. AuthenticatorGetAssertionResponse&& that) = default;
  63. AuthenticatorGetAssertionResponse& AuthenticatorGetAssertionResponse::operator=(
  64. AuthenticatorGetAssertionResponse&& other) = default;
  65. AuthenticatorGetAssertionResponse::~AuthenticatorGetAssertionResponse() =
  66. default;
  67. } // namespace device