fido_parsing_utils.cc 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. // Copyright 2017 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/fido_parsing_utils.h"
  5. #include "base/check_op.h"
  6. #include "base/numerics/safe_conversions.h"
  7. #include "base/strings/stringprintf.h"
  8. namespace device {
  9. namespace fido_parsing_utils {
  10. namespace {
  11. constexpr bool AreSpansDisjoint(base::span<const uint8_t> lhs,
  12. base::span<const uint8_t> rhs) {
  13. return lhs.data() + lhs.size() <= rhs.data() || // [lhs)...[rhs)
  14. rhs.data() + rhs.size() <= lhs.data(); // [rhs)...[lhs)
  15. }
  16. } // namespace
  17. const char kEs256[] = "ES256";
  18. std::vector<uint8_t> Materialize(base::span<const uint8_t> span) {
  19. return std::vector<uint8_t>(span.begin(), span.end());
  20. }
  21. absl::optional<std::vector<uint8_t>> MaterializeOrNull(
  22. absl::optional<base::span<const uint8_t>> span) {
  23. if (span)
  24. return Materialize(*span);
  25. return absl::nullopt;
  26. }
  27. void Append(std::vector<uint8_t>* target, base::span<const uint8_t> in_values) {
  28. CHECK(AreSpansDisjoint(*target, in_values));
  29. target->insert(target->end(), in_values.begin(), in_values.end());
  30. }
  31. std::vector<uint8_t> Extract(base::span<const uint8_t> span,
  32. size_t pos,
  33. size_t length) {
  34. return Materialize(ExtractSpan(span, pos, length));
  35. }
  36. base::span<const uint8_t> ExtractSpan(base::span<const uint8_t> span,
  37. size_t pos,
  38. size_t length) {
  39. if (!(pos <= span.size() && length <= span.size() - pos))
  40. return base::span<const uint8_t>();
  41. return span.subspan(pos, length);
  42. }
  43. std::vector<uint8_t> ExtractSuffix(base::span<const uint8_t> span, size_t pos) {
  44. return Materialize(ExtractSuffixSpan(span, pos));
  45. }
  46. base::span<const uint8_t> ExtractSuffixSpan(base::span<const uint8_t> span,
  47. size_t pos) {
  48. return span.subspan(std::min(pos, span.size()));
  49. }
  50. std::vector<base::span<const uint8_t>> SplitSpan(base::span<const uint8_t> span,
  51. size_t max_chunk_size) {
  52. DCHECK_NE(0u, max_chunk_size);
  53. std::vector<base::span<const uint8_t>> chunks;
  54. const size_t num_chunks = (span.size() + max_chunk_size - 1) / max_chunk_size;
  55. chunks.reserve(num_chunks);
  56. while (!span.empty()) {
  57. const size_t chunk_size = std::min(span.size(), max_chunk_size);
  58. chunks.emplace_back(span.subspan(0, chunk_size));
  59. span = span.subspan(chunk_size);
  60. }
  61. return chunks;
  62. }
  63. std::array<uint8_t, crypto::kSHA256Length> CreateSHA256Hash(
  64. base::StringPiece data) {
  65. std::array<uint8_t, crypto::kSHA256Length> hashed_data;
  66. crypto::SHA256HashString(data, hashed_data.data(), hashed_data.size());
  67. return hashed_data;
  68. }
  69. base::StringPiece ConvertToStringPiece(base::span<const uint8_t> data) {
  70. return {reinterpret_cast<const char*>(data.data()), data.size()};
  71. }
  72. std::string ConvertBytesToUuid(base::span<const uint8_t, 16> bytes) {
  73. uint64_t most_significant_bytes = 0;
  74. for (size_t i = 0; i < sizeof(uint64_t); i++) {
  75. most_significant_bytes |= base::strict_cast<uint64_t>(bytes[i])
  76. << 8 * (7 - i);
  77. }
  78. uint64_t least_significant_bytes = 0;
  79. for (size_t i = 0; i < sizeof(uint64_t); i++) {
  80. least_significant_bytes |= base::strict_cast<uint64_t>(bytes[i + 8])
  81. << 8 * (7 - i);
  82. }
  83. return base::StringPrintf(
  84. "%08x-%04x-%04x-%04x-%012llx",
  85. static_cast<unsigned int>(most_significant_bytes >> 32),
  86. static_cast<unsigned int>((most_significant_bytes >> 16) & 0x0000ffff),
  87. static_cast<unsigned int>(most_significant_bytes & 0x0000ffff),
  88. static_cast<unsigned int>(least_significant_bytes >> 48),
  89. least_significant_bytes & 0x0000ffff'ffffffffULL);
  90. }
  91. } // namespace fido_parsing_utils
  92. } // namespace device