Bumping gaia.json for 8 gaia revision(s) a=gaia-bump
[gecko.git] / dom / base / Crypto.cpp
blob7d0812cf6ea8772925b1ea47858d6709be6b1180
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
4 #include "Crypto.h"
5 #include "jsfriendapi.h"
6 #include "nsCOMPtr.h"
7 #include "nsIRandomGenerator.h"
8 #include "MainThreadUtils.h"
9 #include "nsXULAppAPI.h"
11 #include "mozilla/dom/ContentChild.h"
12 #include "mozilla/dom/CryptoBinding.h"
13 #include "nsServiceManagerUtils.h"
15 using mozilla::dom::ContentChild;
17 namespace mozilla {
18 namespace dom {
20 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Crypto)
21 NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
22 NS_INTERFACE_MAP_ENTRY(nsISupports)
23 NS_INTERFACE_MAP_ENTRY(nsIDOMCrypto)
24 NS_INTERFACE_MAP_END
26 NS_IMPL_CYCLE_COLLECTING_ADDREF(Crypto)
27 NS_IMPL_CYCLE_COLLECTING_RELEASE(Crypto)
29 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(Crypto, mParent, mSubtle)
31 Crypto::Crypto()
33 MOZ_COUNT_CTOR(Crypto);
36 Crypto::~Crypto()
38 MOZ_COUNT_DTOR(Crypto);
41 void
42 Crypto::Init(nsIGlobalObject* aParent)
44 mParent = do_QueryInterface(aParent);
45 MOZ_ASSERT(mParent);
48 /* virtual */ JSObject*
49 Crypto::WrapObject(JSContext* aCx)
51 return CryptoBinding::Wrap(aCx, this);
54 void
55 Crypto::GetRandomValues(JSContext* aCx, const ArrayBufferView& aArray,
56 JS::MutableHandle<JSObject*> aRetval,
57 ErrorResult& aRv)
59 NS_ABORT_IF_FALSE(NS_IsMainThread(), "Called on the wrong thread");
61 JS::Rooted<JSObject*> view(aCx, aArray.Obj());
63 // Throw if the wrong type of ArrayBufferView is passed in
64 // (Part of the Web Crypto API spec)
65 switch (JS_GetArrayBufferViewType(view)) {
66 case js::Scalar::Int8:
67 case js::Scalar::Uint8:
68 case js::Scalar::Uint8Clamped:
69 case js::Scalar::Int16:
70 case js::Scalar::Uint16:
71 case js::Scalar::Int32:
72 case js::Scalar::Uint32:
73 break;
74 default:
75 aRv.Throw(NS_ERROR_DOM_TYPE_MISMATCH_ERR);
76 return;
79 aArray.ComputeLengthAndData();
80 uint32_t dataLen = aArray.Length();
81 if (dataLen == 0) {
82 NS_WARNING("ArrayBufferView length is 0, cannot continue");
83 aRetval.set(view);
84 return;
85 } else if (dataLen > 65536) {
86 aRv.Throw(NS_ERROR_DOM_QUOTA_EXCEEDED_ERR);
87 return;
90 uint8_t* data = aArray.Data();
92 if (XRE_GetProcessType() != GeckoProcessType_Default) {
93 InfallibleTArray<uint8_t> randomValues;
94 // Tell the parent process to generate random values via PContent
95 ContentChild* cc = ContentChild::GetSingleton();
96 if (!cc->SendGetRandomValues(dataLen, &randomValues) ||
97 randomValues.Length() == 0) {
98 aRv.Throw(NS_ERROR_FAILURE);
99 return;
101 NS_ASSERTION(dataLen == randomValues.Length(),
102 "Invalid length returned from parent process!");
103 memcpy(data, randomValues.Elements(), dataLen);
104 } else {
105 uint8_t *buf = GetRandomValues(dataLen);
107 if (!buf) {
108 aRv.Throw(NS_ERROR_FAILURE);
109 return;
112 memcpy(data, buf, dataLen);
113 NS_Free(buf);
116 aRetval.set(view);
119 SubtleCrypto*
120 Crypto::Subtle()
122 if(!mSubtle) {
123 mSubtle = new SubtleCrypto(GetParentObject());
125 return mSubtle;
128 /* static */ uint8_t*
129 Crypto::GetRandomValues(uint32_t aLength)
131 nsCOMPtr<nsIRandomGenerator> randomGenerator;
132 nsresult rv;
133 randomGenerator = do_GetService("@mozilla.org/security/random-generator;1");
134 NS_ENSURE_TRUE(randomGenerator, nullptr);
136 uint8_t* buf;
137 rv = randomGenerator->GenerateRandomBytes(aLength, &buf);
139 NS_ENSURE_SUCCESS(rv, nullptr);
141 return buf;
144 } // namespace dom
145 } // namespace mozilla