dom/base/Crypto.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
michael@0 3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4 #include "Crypto.h"
michael@0 5 #include "jsfriendapi.h"
michael@0 6 #include "nsCOMPtr.h"
michael@0 7 #include "nsIRandomGenerator.h"
michael@0 8 #include "nsPIDOMWindow.h"
michael@0 9 #include "MainThreadUtils.h"
michael@0 10 #include "nsXULAppAPI.h"
michael@0 11
michael@0 12 #include "mozilla/dom/ContentChild.h"
michael@0 13 #include "mozilla/dom/CryptoBinding.h"
michael@0 14 #include "nsServiceManagerUtils.h"
michael@0 15
michael@0 16 using mozilla::dom::ContentChild;
michael@0 17
michael@0 18 using namespace js::ArrayBufferView;
michael@0 19
michael@0 20 namespace mozilla {
michael@0 21 namespace dom {
michael@0 22
michael@0 23 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Crypto)
michael@0 24 NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
michael@0 25 NS_INTERFACE_MAP_ENTRY(nsISupports)
michael@0 26 NS_INTERFACE_MAP_ENTRY(nsIDOMCrypto)
michael@0 27 NS_INTERFACE_MAP_END
michael@0 28
michael@0 29 NS_IMPL_CYCLE_COLLECTING_ADDREF(Crypto)
michael@0 30 NS_IMPL_CYCLE_COLLECTING_RELEASE(Crypto)
michael@0 31
michael@0 32 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_1(Crypto, mWindow)
michael@0 33
michael@0 34 Crypto::Crypto()
michael@0 35 {
michael@0 36 MOZ_COUNT_CTOR(Crypto);
michael@0 37 SetIsDOMBinding();
michael@0 38 }
michael@0 39
michael@0 40 Crypto::~Crypto()
michael@0 41 {
michael@0 42 MOZ_COUNT_DTOR(Crypto);
michael@0 43 }
michael@0 44
michael@0 45 void
michael@0 46 Crypto::Init(nsIDOMWindow* aWindow)
michael@0 47 {
michael@0 48 mWindow = do_QueryInterface(aWindow);
michael@0 49 MOZ_ASSERT(mWindow);
michael@0 50 }
michael@0 51
michael@0 52 /* virtual */ JSObject*
michael@0 53 Crypto::WrapObject(JSContext* aCx)
michael@0 54 {
michael@0 55 return CryptoBinding::Wrap(aCx, this);
michael@0 56 }
michael@0 57
michael@0 58 void
michael@0 59 Crypto::GetRandomValues(JSContext* aCx, const ArrayBufferView& aArray,
michael@0 60 JS::MutableHandle<JSObject*> aRetval,
michael@0 61 ErrorResult& aRv)
michael@0 62 {
michael@0 63 NS_ABORT_IF_FALSE(NS_IsMainThread(), "Called on the wrong thread");
michael@0 64
michael@0 65 JS::Rooted<JSObject*> view(aCx, aArray.Obj());
michael@0 66
michael@0 67 // Throw if the wrong type of ArrayBufferView is passed in
michael@0 68 // (Part of the Web Crypto API spec)
michael@0 69 switch (JS_GetArrayBufferViewType(view)) {
michael@0 70 case TYPE_INT8:
michael@0 71 case TYPE_UINT8:
michael@0 72 case TYPE_UINT8_CLAMPED:
michael@0 73 case TYPE_INT16:
michael@0 74 case TYPE_UINT16:
michael@0 75 case TYPE_INT32:
michael@0 76 case TYPE_UINT32:
michael@0 77 break;
michael@0 78 default:
michael@0 79 aRv.Throw(NS_ERROR_DOM_TYPE_MISMATCH_ERR);
michael@0 80 return;
michael@0 81 }
michael@0 82
michael@0 83 aArray.ComputeLengthAndData();
michael@0 84 uint32_t dataLen = aArray.Length();
michael@0 85 if (dataLen == 0) {
michael@0 86 NS_WARNING("ArrayBufferView length is 0, cannot continue");
michael@0 87 aRetval.set(view);
michael@0 88 return;
michael@0 89 } else if (dataLen > 65536) {
michael@0 90 aRv.Throw(NS_ERROR_DOM_QUOTA_EXCEEDED_ERR);
michael@0 91 return;
michael@0 92 }
michael@0 93
michael@0 94 uint8_t* data = aArray.Data();
michael@0 95
michael@0 96 if (XRE_GetProcessType() != GeckoProcessType_Default) {
michael@0 97 InfallibleTArray<uint8_t> randomValues;
michael@0 98 // Tell the parent process to generate random values via PContent
michael@0 99 ContentChild* cc = ContentChild::GetSingleton();
michael@0 100 if (!cc->SendGetRandomValues(dataLen, &randomValues) ||
michael@0 101 randomValues.Length() == 0) {
michael@0 102 aRv.Throw(NS_ERROR_FAILURE);
michael@0 103 return;
michael@0 104 }
michael@0 105 NS_ASSERTION(dataLen == randomValues.Length(),
michael@0 106 "Invalid length returned from parent process!");
michael@0 107 memcpy(data, randomValues.Elements(), dataLen);
michael@0 108 } else {
michael@0 109 uint8_t *buf = GetRandomValues(dataLen);
michael@0 110
michael@0 111 if (!buf) {
michael@0 112 aRv.Throw(NS_ERROR_FAILURE);
michael@0 113 return;
michael@0 114 }
michael@0 115
michael@0 116 memcpy(data, buf, dataLen);
michael@0 117 NS_Free(buf);
michael@0 118 }
michael@0 119
michael@0 120 aRetval.set(view);
michael@0 121 }
michael@0 122
michael@0 123 #ifndef MOZ_DISABLE_CRYPTOLEGACY
michael@0 124 // Stub out the legacy nsIDOMCrypto methods. The actual
michael@0 125 // implementations are in security/manager/ssl/src/nsCrypto.{cpp,h}
michael@0 126
michael@0 127 NS_IMETHODIMP
michael@0 128 Crypto::GetEnableSmartCardEvents(bool *aEnableSmartCardEvents)
michael@0 129 {
michael@0 130 return NS_ERROR_NOT_IMPLEMENTED;
michael@0 131 }
michael@0 132
michael@0 133 NS_IMETHODIMP
michael@0 134 Crypto::SetEnableSmartCardEvents(bool aEnableSmartCardEvents)
michael@0 135 {
michael@0 136 return NS_ERROR_NOT_IMPLEMENTED;
michael@0 137 }
michael@0 138
michael@0 139 bool
michael@0 140 Crypto::EnableSmartCardEvents()
michael@0 141 {
michael@0 142 return false;
michael@0 143 }
michael@0 144
michael@0 145 void
michael@0 146 Crypto::SetEnableSmartCardEvents(bool aEnable, ErrorResult& aRv)
michael@0 147 {
michael@0 148 aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
michael@0 149 }
michael@0 150
michael@0 151 void
michael@0 152 Crypto::GetVersion(nsString& aVersion)
michael@0 153 {
michael@0 154 }
michael@0 155
michael@0 156 mozilla::dom::CRMFObject*
michael@0 157 Crypto::GenerateCRMFRequest(JSContext* aContext,
michael@0 158 const nsCString& aReqDN,
michael@0 159 const nsCString& aRegToken,
michael@0 160 const nsCString& aAuthenticator,
michael@0 161 const nsCString& aEaCert,
michael@0 162 const nsCString& aJsCallback,
michael@0 163 const Sequence<JS::Value>& aArgs,
michael@0 164 ErrorResult& aRv)
michael@0 165 {
michael@0 166 aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
michael@0 167 return nullptr;
michael@0 168 }
michael@0 169
michael@0 170 void
michael@0 171 Crypto::ImportUserCertificates(const nsAString& aNickname,
michael@0 172 const nsAString& aCmmfResponse,
michael@0 173 bool aDoForcedBackup,
michael@0 174 nsAString& aReturn,
michael@0 175 ErrorResult& aRv)
michael@0 176 {
michael@0 177 aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
michael@0 178 }
michael@0 179
michael@0 180 void
michael@0 181 Crypto::SignText(JSContext* aContext,
michael@0 182 const nsAString& aStringToSign,
michael@0 183 const nsAString& aCaOption,
michael@0 184 const Sequence<nsCString>& aArgs,
michael@0 185 nsAString& aReturn)
michael@0 186
michael@0 187 {
michael@0 188 aReturn.AssignLiteral("error:internalError");
michael@0 189 }
michael@0 190
michael@0 191 void
michael@0 192 Crypto::Logout(ErrorResult& aRv)
michael@0 193 {
michael@0 194 aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
michael@0 195 }
michael@0 196
michael@0 197 #endif
michael@0 198
michael@0 199 /* static */ uint8_t*
michael@0 200 Crypto::GetRandomValues(uint32_t aLength)
michael@0 201 {
michael@0 202 nsCOMPtr<nsIRandomGenerator> randomGenerator;
michael@0 203 nsresult rv;
michael@0 204 randomGenerator = do_GetService("@mozilla.org/security/random-generator;1");
michael@0 205 NS_ENSURE_TRUE(randomGenerator, nullptr);
michael@0 206
michael@0 207 uint8_t* buf;
michael@0 208 rv = randomGenerator->GenerateRandomBytes(aLength, &buf);
michael@0 209
michael@0 210 NS_ENSURE_SUCCESS(rv, nullptr);
michael@0 211
michael@0 212 return buf;
michael@0 213 }
michael@0 214
michael@0 215 } // namespace dom
michael@0 216 } // namespace mozilla

mercurial