|
1 | | -// TODO: remove these once the warnings are fixed |
2 | | -#pragma clang diagnostic push |
3 | | -#pragma clang diagnostic ignored "-Winvalid-offsetof" |
4 | | -#pragma clang diagnostic ignored "-Wdeprecated-enum-enum-conversion" |
5 | | -#include "js/experimental/TypedData.h" // used in "js/Conversions.h" |
6 | | -#pragma clang diagnostic pop |
7 | | - |
8 | 1 | #include "../dom-exception.h" |
9 | 2 | #include "crypto.h" |
10 | 3 | #include "host_api.h" |
11 | 4 | #include "subtle-crypto.h" |
| 5 | +#include "uuid.h" |
12 | 6 |
|
13 | 7 | bool is_int_typed_array(JSObject *obj) { |
14 | 8 | return JS_IsInt8Array(obj) || JS_IsUint8Array(obj) || JS_IsInt16Array(obj) || |
@@ -66,114 +60,18 @@ bool Crypto::get_random_values(JSContext *cx, unsigned argc, JS::Value *vp) { |
66 | 60 | return true; |
67 | 61 | } |
68 | 62 |
|
69 | | -/* |
70 | | - FROM RFC 4122 |
71 | | - The formal definition of the UUID string representation is |
72 | | - provided by the following ABNF [7]: |
73 | | -
|
74 | | - UUID = time-low "-" time-mid "-" |
75 | | - time-high-and-version "-" |
76 | | - clock-seq-and-reserved |
77 | | - clock-seq-low "-" node |
78 | | - time-low = 4hexOctet |
79 | | - time-mid = 2hexOctet |
80 | | - time-high-and-version = 2hexOctet |
81 | | - clock-seq-and-reserved = hexOctet |
82 | | - clock-seq-low = hexOctet |
83 | | - node = 6hexOctet |
84 | | - hexOctet = hexDigit hexDigit |
85 | | - hexDigit = |
86 | | - "0" / "1" / "2" / "3" / "4" / "5" / "6" / "7" / "8" / "9" / |
87 | | - "a" / "b" / "c" / "d" / "e" / "f" / |
88 | | - "A" / "B" / "C" / "D" / "E" / "F" |
89 | | -*/ |
90 | | -struct UUID { |
91 | | - uint32_t time_low; |
92 | | - uint16_t time_mid; |
93 | | - uint16_t time_high_and_version; |
94 | | - uint8_t clock_seq_and_reserved; |
95 | | - uint8_t clock_seq_low; |
96 | | - uint8_t node[6]; |
97 | | -}; |
98 | | - |
99 | | -/* |
100 | | - FROM RFC 4122 |
101 | | - 4.1.3. Version |
102 | | -
|
103 | | - The version number is in the most significant 4 bits of the time |
104 | | - stamp (bits 4 through 7 of the time_hi_and_version field). |
105 | | -
|
106 | | - The following table lists the currently-defined versions for this |
107 | | - UUID variant. |
108 | | -
|
109 | | - Msb0 Msb1 Msb2 Msb3 Version Description |
110 | | -
|
111 | | - 0 0 0 1 1 The time-based version |
112 | | - specified in this document. |
113 | | -
|
114 | | - 0 0 1 0 2 DCE Security version, with |
115 | | - embedded POSIX UIDs. |
116 | | -
|
117 | | - 0 0 1 1 3 The name-based version |
118 | | - specified in this document |
119 | | - that uses MD5 hashing. |
120 | | -
|
121 | | - 0 1 0 0 4 The randomly or pseudo- |
122 | | - randomly generated version |
123 | | - specified in this document. |
124 | | -
|
125 | | - 0 1 0 1 5 The name-based version |
126 | | - specified in this document |
127 | | - that uses SHA-1 hashing. |
128 | | -*/ |
129 | | -/* |
130 | | - FROM RFC 4122 |
131 | | - The version 4 UUID is meant for generating UUIDs from truly-random or |
132 | | - pseudo-random numbers. |
133 | | -
|
134 | | - The algorithm is as follows: |
135 | | -
|
136 | | - Set the two most significant bits (bits 6 and 7) of the clock_seq_hi_and_reserved to zero and one, |
137 | | - respectively. |
138 | | -
|
139 | | - Set the four most significant bits (bits 12 through 15) of the time_hi_and_version field to the |
140 | | - 4-bit version number from Section 4.1.3. |
141 | | -
|
142 | | - Set all the other bits to randomly (or pseudo-randomly) chosen values. |
143 | | -*/ |
144 | 63 | bool Crypto::random_uuid(JSContext *cx, unsigned argc, JS::Value *vp) { |
145 | 64 | METHOD_HEADER(0) |
146 | | - UUID id; |
147 | 65 |
|
148 | | - { |
149 | | - auto res = host_api::Random::get_bytes(sizeof(id)); |
150 | | - if (auto *err = res.to_err()) { |
151 | | - HANDLE_ERROR(cx, *err); |
152 | | - return false; |
153 | | - } |
154 | | - |
155 | | - auto bytes = std::move(res.unwrap()); |
156 | | - std::copy_n(bytes.begin(), sizeof(id), reinterpret_cast<uint8_t *>(&id)); |
| 66 | + auto maybe_uuid = random_uuid_v4(cx); |
| 67 | + if (!maybe_uuid.has_value()) { |
| 68 | + return false; |
157 | 69 | } |
158 | 70 |
|
159 | | - // Set the two most significant bits (bits 6 and 7) of the clock_seq_hi_and_reserved to zero and |
160 | | - // one, respectively. |
161 | | - id.clock_seq_and_reserved &= 0x3f; |
162 | | - id.clock_seq_and_reserved |= 0x80; |
163 | | - // Set the four most significant bits (bits 12 through 15) of the time_hi_and_version field to the |
164 | | - // 4-bit version number from Section 4.1.3. |
165 | | - id.time_high_and_version &= 0x0fff; |
166 | | - id.time_high_and_version |= 0x4000; |
167 | | - |
168 | | - const char *fmt = "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x"; |
169 | | - char buf[80]; |
170 | | - std::snprintf(buf, sizeof(buf) - 1, fmt, id.time_low, (uint32_t)id.time_mid, |
171 | | - (uint32_t)id.time_high_and_version, (uint32_t)id.clock_seq_and_reserved, |
172 | | - (uint32_t)id.clock_seq_low, (uint32_t)id.node[0], (uint32_t)id.node[1], |
173 | | - (uint32_t)id.node[2], (uint32_t)id.node[3], (uint32_t)id.node[4], |
174 | | - (uint32_t)id.node[5]); |
175 | | - JS::RootedString str(cx, JS_NewStringCopyN(cx, buf, 36)); |
| 71 | + auto uuid = maybe_uuid.value(); |
| 72 | + MOZ_ASSERT(uuid.size() == 36); |
176 | 73 |
|
| 74 | + JS::RootedString str(cx, JS_NewStringCopyN(cx, uuid.data(), uuid.size())); |
177 | 75 | if (!str) { |
178 | 76 | return false; |
179 | 77 | } |
|
0 commit comments