Bug 1660051 [wpt PR 25111] - Origin isolation: expand getter test coverage, a=testonly
[gecko.git] / dom / base / Crypto.cpp
blob5dec7c8466a26d745918ca09debb9486b9f958bb
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "Crypto.h"
7 #include "jsfriendapi.h"
8 #include "js/experimental/TypedData.h" // JS_GetArrayBufferViewType
9 #include "nsCOMPtr.h"
10 #include "nsIRandomGenerator.h"
11 #include "MainThreadUtils.h"
12 #include "nsXULAppAPI.h"
14 #include "mozilla/dom/ContentChild.h"
15 #include "mozilla/dom/CryptoBinding.h"
16 #include "nsServiceManagerUtils.h"
18 using mozilla::dom::ContentChild;
20 namespace mozilla {
21 namespace dom {
23 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Crypto)
24 NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
25 NS_INTERFACE_MAP_ENTRY(nsISupports)
26 NS_INTERFACE_MAP_END
28 NS_IMPL_CYCLE_COLLECTING_ADDREF(Crypto)
29 NS_IMPL_CYCLE_COLLECTING_RELEASE(Crypto)
31 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(Crypto, mParent, mSubtle)
33 Crypto::Crypto(nsIGlobalObject* aParent) : mParent(aParent) {}
35 Crypto::~Crypto() = default;
37 /* virtual */
38 JSObject* Crypto::WrapObject(JSContext* aCx,
39 JS::Handle<JSObject*> aGivenProto) {
40 return Crypto_Binding::Wrap(aCx, this, aGivenProto);
43 void Crypto::GetRandomValues(JSContext* aCx, const ArrayBufferView& aArray,
44 JS::MutableHandle<JSObject*> aRetval,
45 ErrorResult& aRv) {
46 JS::Rooted<JSObject*> view(aCx, aArray.Obj());
48 // Throw if the wrong type of ArrayBufferView is passed in
49 // (Part of the Web Crypto API spec)
50 switch (JS_GetArrayBufferViewType(view)) {
51 case js::Scalar::Int8:
52 case js::Scalar::Uint8:
53 case js::Scalar::Uint8Clamped:
54 case js::Scalar::Int16:
55 case js::Scalar::Uint16:
56 case js::Scalar::Int32:
57 case js::Scalar::Uint32:
58 break;
59 default:
60 aRv.Throw(NS_ERROR_DOM_TYPE_MISMATCH_ERR);
61 return;
64 aArray.ComputeState();
65 uint32_t dataLen = aArray.Length();
66 if (dataLen == 0) {
67 NS_WARNING("ArrayBufferView length is 0, cannot continue");
68 aRetval.set(view);
69 return;
70 } else if (dataLen > 65536) {
71 aRv.Throw(NS_ERROR_DOM_QUOTA_EXCEEDED_ERR);
72 return;
75 nsCOMPtr<nsIRandomGenerator> randomGenerator =
76 do_GetService("@mozilla.org/security/random-generator;1");
77 if (!randomGenerator) {
78 aRv.Throw(NS_ERROR_DOM_OPERATION_ERR);
79 return;
82 uint8_t* buf;
83 nsresult rv = randomGenerator->GenerateRandomBytes(dataLen, &buf);
84 if (NS_FAILED(rv) || !buf) {
85 aRv.Throw(NS_ERROR_DOM_OPERATION_ERR);
86 return;
89 // Copy random bytes to ABV.
90 memcpy(aArray.Data(), buf, dataLen);
91 free(buf);
93 aRetval.set(view);
96 SubtleCrypto* Crypto::Subtle() {
97 if (!mSubtle) {
98 mSubtle = new SubtleCrypto(GetParentObject());
100 return mSubtle;
103 } // namespace dom
104 } // namespace mozilla