Skip to content

Commit

Permalink
Add create/revoke URL object methods
Browse files Browse the repository at this point in the history
  • Loading branch information
andreiltd committed Dec 19, 2024
1 parent 9b26b51 commit e43472b
Show file tree
Hide file tree
Showing 16 changed files with 818 additions and 176 deletions.
1 change: 1 addition & 0 deletions builtins/web/crypto/crypto-algorithm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1841,6 +1841,7 @@ JSObject *CryptoAlgorithmRSASSA_PKCS1_v1_5_Import::importKey(JSContext *cx, Cryp
case CryptoKeyFormat::Spki:
case CryptoKeyFormat::Pkcs8: {
// TODO: Add implementations for these
[[fallthrough]];
}
default: {
DOMException::raise(cx, "Supplied format is not supported", "DataError");
Expand Down
116 changes: 7 additions & 109 deletions builtins/web/crypto/crypto.cpp
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
// TODO: remove these once the warnings are fixed
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Winvalid-offsetof"
#pragma clang diagnostic ignored "-Wdeprecated-enum-enum-conversion"
#include "js/experimental/TypedData.h" // used in "js/Conversions.h"
#pragma clang diagnostic pop

#include "../dom-exception.h"
#include "crypto.h"
#include "host_api.h"
#include "subtle-crypto.h"
#include "uuid.h"

bool is_int_typed_array(JSObject *obj) {
return JS_IsInt8Array(obj) || JS_IsUint8Array(obj) || JS_IsInt16Array(obj) ||
Expand Down Expand Up @@ -66,114 +60,18 @@ bool Crypto::get_random_values(JSContext *cx, unsigned argc, JS::Value *vp) {
return true;
}

/*
FROM RFC 4122
The formal definition of the UUID string representation is
provided by the following ABNF [7]:
UUID = time-low "-" time-mid "-"
time-high-and-version "-"
clock-seq-and-reserved
clock-seq-low "-" node
time-low = 4hexOctet
time-mid = 2hexOctet
time-high-and-version = 2hexOctet
clock-seq-and-reserved = hexOctet
clock-seq-low = hexOctet
node = 6hexOctet
hexOctet = hexDigit hexDigit
hexDigit =
"0" / "1" / "2" / "3" / "4" / "5" / "6" / "7" / "8" / "9" /
"a" / "b" / "c" / "d" / "e" / "f" /
"A" / "B" / "C" / "D" / "E" / "F"
*/
struct UUID {
uint32_t time_low;
uint16_t time_mid;
uint16_t time_high_and_version;
uint8_t clock_seq_and_reserved;
uint8_t clock_seq_low;
uint8_t node[6];
};

/*
FROM RFC 4122
4.1.3. Version
The version number is in the most significant 4 bits of the time
stamp (bits 4 through 7 of the time_hi_and_version field).
The following table lists the currently-defined versions for this
UUID variant.
Msb0 Msb1 Msb2 Msb3 Version Description
0 0 0 1 1 The time-based version
specified in this document.
0 0 1 0 2 DCE Security version, with
embedded POSIX UIDs.
0 0 1 1 3 The name-based version
specified in this document
that uses MD5 hashing.
0 1 0 0 4 The randomly or pseudo-
randomly generated version
specified in this document.
0 1 0 1 5 The name-based version
specified in this document
that uses SHA-1 hashing.
*/
/*
FROM RFC 4122
The version 4 UUID is meant for generating UUIDs from truly-random or
pseudo-random numbers.
The algorithm is as follows:
Set the two most significant bits (bits 6 and 7) of the clock_seq_hi_and_reserved to zero and one,
respectively.
Set the four most significant bits (bits 12 through 15) of the time_hi_and_version field to the
4-bit version number from Section 4.1.3.
Set all the other bits to randomly (or pseudo-randomly) chosen values.
*/
bool Crypto::random_uuid(JSContext *cx, unsigned argc, JS::Value *vp) {
METHOD_HEADER(0)
UUID id;

{
auto res = host_api::Random::get_bytes(sizeof(id));
if (auto *err = res.to_err()) {
HANDLE_ERROR(cx, *err);
return false;
}

auto bytes = std::move(res.unwrap());
std::copy_n(bytes.begin(), sizeof(id), reinterpret_cast<uint8_t *>(&id));
auto maybe_uuid = random_uuid_v4(cx);
if (!maybe_uuid.has_value()) {
return false;
}

// Set the two most significant bits (bits 6 and 7) of the clock_seq_hi_and_reserved to zero and
// one, respectively.
id.clock_seq_and_reserved &= 0x3f;
id.clock_seq_and_reserved |= 0x80;
// Set the four most significant bits (bits 12 through 15) of the time_hi_and_version field to the
// 4-bit version number from Section 4.1.3.
id.time_high_and_version &= 0x0fff;
id.time_high_and_version |= 0x4000;

const char *fmt = "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x";
char buf[80];
std::snprintf(buf, sizeof(buf) - 1, fmt, id.time_low, (uint32_t)id.time_mid,
(uint32_t)id.time_high_and_version, (uint32_t)id.clock_seq_and_reserved,
(uint32_t)id.clock_seq_low, (uint32_t)id.node[0], (uint32_t)id.node[1],
(uint32_t)id.node[2], (uint32_t)id.node[3], (uint32_t)id.node[4],
(uint32_t)id.node[5]);
JS::RootedString str(cx, JS_NewStringCopyN(cx, buf, 36));
auto uuid = maybe_uuid.value();
MOZ_ASSERT(uuid.size() == 36);

JS::RootedString str(cx, JS_NewStringCopyN(cx, uuid.data(), uuid.size()));
if (!str) {
return false;
}
Expand Down
100 changes: 100 additions & 0 deletions builtins/web/crypto/uuid.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
#include "uuid.h"
#include "host_api.h"

#include <fmt/core.h>

namespace builtins {
namespace web {
namespace crypto {

// FROM RFC 4122
// The formal definition of the UUID string representation is
// provided by the following ABNF [7]:
//
// UUID = time-low "-" time-mid "-"
// time-high-and-version "-"
// clock-seq-and-reserved
// clock-seq-low "-" node
// time-low = 4hexOctet
// time-mid = 2hexOctet
// time-high-and-version = 2hexOctet
// clock-seq-and-reserved = hexOctet
// clock-seq-low = hexOctet
// node = 6hexOctet
// hexOctet = hexDigit hexDigit
// hexDigit =
// "0" / "1" / "2" / "3" / "4" / "5" / "6" / "7" / "8" / "9" /
// "a" / "b" / "c" / "d" / "e" / "f" /
// "A" / "B" / "C" / "D" / "E" / "F"
struct UUID {
uint32_t time_low;
uint16_t time_mid;
uint16_t time_high_and_version;
uint8_t clock_seq_and_reserved;
uint8_t clock_seq_low;
uint8_t node[6];
};

// FROM RFC 4122
// 4.1.3. Version
//
// The version number is in the most significant 4 bits of the time
// stamp (bits 4 through 7 of the time_hi_and_version field).
//
// The following table lists the currently-defined versions for this
// UUID variant.
//
// Msb0 Msb1 Msb2 Msb3 Version Description
//
// 0 0 0 1 1 The time-based version
// specified in this document.
//
// 0 0 1 0 2 DCE Security version, with
// embedded POSIX UIDs.
//
// 0 0 1 1 3 The name-based version
// specified in this document
// that uses MD5 hashing.
//
// 0 1 0 0 4 The randomly or pseudo-
// randomly generated version
// specified in this document.
//
// 0 1 0 1 5 The name-based version
// specified in this document
// that uses SHA-1 hashing.
std::optional<std::string> random_uuid_v4(JSContext *cx) {
UUID id;

{
auto res = host_api::Random::get_bytes(sizeof(id));
if (auto *err = res.to_err()) {
HANDLE_ERROR(cx, *err);
return std::nullopt;
}

auto bytes = std::move(res.unwrap());
std::copy_n(bytes.begin(), sizeof(id), reinterpret_cast<uint8_t *>(&id));
}

// Set the two most significant bits (bits 6 and 7) of the clock_seq_hi_and_reserved to zero and
// one, respectively.
id.clock_seq_and_reserved &= 0x3f;
id.clock_seq_and_reserved |= 0x80;
// Set the four most significant bits (bits 12 through 15) of the time_hi_and_version field to the
// 4-bit version number from Section 4.1.3.
id.time_high_and_version &= 0x0fff;
id.time_high_and_version |= 0x4000;

return fmt::format("{:08x}-{:04x}-{:04x}-{:02x}{:02x}-{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}",
id.time_low,
id.time_mid,
id.time_high_and_version,
id.clock_seq_and_reserved, id.clock_seq_low,
id.node[0], id.node[1], id.node[2],
id.node[3], id.node[4], id.node[5]);
}

} // namespace uuid
} // namespace web
} // namespace builtins
29 changes: 29 additions & 0 deletions builtins/web/crypto/uuid.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#ifndef BUILTINS_WEB_CRYPTO_UUID_H
#define BUILTINS_WEB_CRYPTO_UUID_H

#include "builtin.h"

namespace builtins {
namespace web {
namespace crypto {

// FROM RFC 4122
// The version 4 UUID is meant for generating UUIDs from truly-random or
// pseudo-random numbers.
//
// The algorithm is as follows:
//
// Set the two most significant bits (bits 6 and 7) of the clock_seq_hi_and_reserved to zero and one,
// respectively.
//
// Set the four most significant bits (bits 12 through 15) of the time_hi_and_version field to the
// 4-bit version number from Section 4.1.3.
//
// Set all the other bits to randomly (or pseudo-randomly) chosen values.
std::optional<std::string> random_uuid_v4(JSContext *cx);

} // namespace crypto
} // namespace web
} // namespace builtins

#endif // BUILTINS_WEB_CRYPTO_UUID_H
Loading

0 comments on commit e43472b

Please sign in to comment.