blob: 1bc546be31fc6daf63aa8e520defe23c3d87dbb9 [file] [log] [blame]
Kim Paulhamus6efcf4952017-09-14 22:46:271// 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
5#ifndef CONTENT_BROWSER_WEBAUTH_CBOR_CBOR_VALUES_H_
6#define CONTENT_BROWSER_WEBAUTH_CBOR_CBOR_VALUES_H_
7
8#include <stdint.h>
9#include <string>
Adam Langley68672fd2017-10-17 19:35:2710#include <tuple>
Kim Paulhamus6efcf4952017-09-14 22:46:2711#include <vector>
12
13#include "base/containers/flat_map.h"
14#include "base/macros.h"
Kim Paulhamus6efcf4952017-09-14 22:46:2715#include "base/strings/string_piece_forward.h"
16#include "content/common/content_export.h"
17
18namespace content {
19
20// A class for Concise Binary Object Representation (CBOR) values.
21// This does not support:
22// * Negative integers.
23// * Floating-point numbers.
24// * Indefinite-length encodings.
25class CONTENT_EXPORT CBORValue {
26 public:
Adam Langley68672fd2017-10-17 19:35:2727 struct CTAPLess {
28 // Comparison predicate to order keys in a dictionary as required by the
29 // Client-to-Authenticator Protocol (CTAP) spec 2.0.
30 //
31 // The sort order defined in CTAP is:
32 // • If the major types are different, the one with the lower value in
33 // numerical order sorts earlier. (Moot in this code because all keys
34 // are strings.)
35 // • If two keys have different lengths, the shorter one sorts earlier.
36 // • If two keys have the same length, the one with the lower value in
37 // (byte-wise) lexical order sorts earlier.
38 //
39 // See section 6 of https://fidoalliance.org/specs/fido-v2.0-rd-20170927/
40 // fido-client-to-authenticator-protocol-v2.0-rd-20170927.html and
41 // https://tools.ietf.org/html/rfc7049#section-3.9 also.
42 bool operator()(const std::string& a, const std::string& b) const {
43 const size_t a_size = a.size();
44 const size_t b_size = b.size();
45 return std::tie(a_size, a) < std::tie(b_size, b);
46 }
47
48 bool operator()(const char* a, const std::string& b) const {
49 return operator()(std::string(a), b);
50 }
51
52 bool operator()(const std::string& a, const char* b) const {
53 return operator()(a, std::string(b));
54 }
55
56 using is_transparent = void;
57 };
58
Kim Paulhamus6efcf4952017-09-14 22:46:2759 using BinaryValue = std::vector<uint8_t>;
60 using ArrayValue = std::vector<CBORValue>;
Adam Langley68672fd2017-10-17 19:35:2761 using MapValue = base::flat_map<std::string, CBORValue, CTAPLess>;
Kim Paulhamus6efcf4952017-09-14 22:46:2762
63 enum class Type {
64 NONE,
65 UNSIGNED,
66 BYTESTRING,
67 STRING,
68 ARRAY,
69 MAP,
70 };
71
72 CBORValue(CBORValue&& that) noexcept;
73 CBORValue() noexcept; // A NONE value.
74
75 explicit CBORValue(Type type);
76 explicit CBORValue(uint64_t in_unsigned);
77
78 explicit CBORValue(const BinaryValue& in_bytes);
79 explicit CBORValue(BinaryValue&& in_bytes) noexcept;
80
81 explicit CBORValue(const char* in_string);
82 explicit CBORValue(std::string&& in_string) noexcept;
83 explicit CBORValue(base::StringPiece in_string);
84
85 explicit CBORValue(const ArrayValue& in_array);
86 explicit CBORValue(ArrayValue&& in_array) noexcept;
87
88 explicit CBORValue(const MapValue& in_map);
89 explicit CBORValue(MapValue&& in_map) noexcept;
90
91 CBORValue& operator=(CBORValue&& that) noexcept;
92
93 ~CBORValue();
94
95 // CBORValue's copy constructor and copy assignment operator are deleted.
96 // Use this to obtain a deep copy explicitly.
97 CBORValue Clone() const;
98
99 // Returns the type of the value stored by the current Value object.
100 Type type() const { return type_; }
101
102 // Returns true if the current object represents a given type.
103 bool is_type(Type type) const { return type == type_; }
104 bool is_none() const { return type() == Type::NONE; }
105 bool is_unsigned() const { return type() == Type::UNSIGNED; }
106 bool is_bytestring() const { return type() == Type::BYTESTRING; }
107 bool is_string() const { return type() == Type::STRING; }
108 bool is_array() const { return type() == Type::ARRAY; }
109 bool is_map() const { return type() == Type::MAP; }
110
111 // These will all fatally assert if the type doesn't match.
112 uint64_t GetUnsigned() const;
113 const BinaryValue& GetBytestring() const;
114 const std::string& GetString() const;
115 const ArrayValue& GetArray() const;
116 const MapValue& GetMap() const;
117
118 private:
119 Type type_;
120
121 union {
122 uint64_t unsigned_value_;
Daniel Cheng9eb43fd342017-10-10 21:28:37123 BinaryValue bytestring_value_;
124 std::string string_value_;
125 ArrayValue array_value_;
126 MapValue map_value_;
Kim Paulhamus6efcf4952017-09-14 22:46:27127 };
128
129 void InternalMoveConstructFrom(CBORValue&& that);
130 void InternalCleanup();
131
132 DISALLOW_COPY_AND_ASSIGN(CBORValue);
133};
134} // namespace content
135
Daniel Cheng9eb43fd342017-10-10 21:28:37136#endif // CONTENT_BROWSER_WEBAUTH_CBOR_CBOR_VALUES_H_