1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/base/Crypto.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,216 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this file, 1.6 + * You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 +#include "Crypto.h" 1.8 +#include "jsfriendapi.h" 1.9 +#include "nsCOMPtr.h" 1.10 +#include "nsIRandomGenerator.h" 1.11 +#include "nsPIDOMWindow.h" 1.12 +#include "MainThreadUtils.h" 1.13 +#include "nsXULAppAPI.h" 1.14 + 1.15 +#include "mozilla/dom/ContentChild.h" 1.16 +#include "mozilla/dom/CryptoBinding.h" 1.17 +#include "nsServiceManagerUtils.h" 1.18 + 1.19 +using mozilla::dom::ContentChild; 1.20 + 1.21 +using namespace js::ArrayBufferView; 1.22 + 1.23 +namespace mozilla { 1.24 +namespace dom { 1.25 + 1.26 +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Crypto) 1.27 + NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY 1.28 + NS_INTERFACE_MAP_ENTRY(nsISupports) 1.29 + NS_INTERFACE_MAP_ENTRY(nsIDOMCrypto) 1.30 +NS_INTERFACE_MAP_END 1.31 + 1.32 +NS_IMPL_CYCLE_COLLECTING_ADDREF(Crypto) 1.33 +NS_IMPL_CYCLE_COLLECTING_RELEASE(Crypto) 1.34 + 1.35 +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_1(Crypto, mWindow) 1.36 + 1.37 +Crypto::Crypto() 1.38 +{ 1.39 + MOZ_COUNT_CTOR(Crypto); 1.40 + SetIsDOMBinding(); 1.41 +} 1.42 + 1.43 +Crypto::~Crypto() 1.44 +{ 1.45 + MOZ_COUNT_DTOR(Crypto); 1.46 +} 1.47 + 1.48 +void 1.49 +Crypto::Init(nsIDOMWindow* aWindow) 1.50 +{ 1.51 + mWindow = do_QueryInterface(aWindow); 1.52 + MOZ_ASSERT(mWindow); 1.53 +} 1.54 + 1.55 +/* virtual */ JSObject* 1.56 +Crypto::WrapObject(JSContext* aCx) 1.57 +{ 1.58 + return CryptoBinding::Wrap(aCx, this); 1.59 +} 1.60 + 1.61 +void 1.62 +Crypto::GetRandomValues(JSContext* aCx, const ArrayBufferView& aArray, 1.63 + JS::MutableHandle<JSObject*> aRetval, 1.64 + ErrorResult& aRv) 1.65 +{ 1.66 + NS_ABORT_IF_FALSE(NS_IsMainThread(), "Called on the wrong thread"); 1.67 + 1.68 + JS::Rooted<JSObject*> view(aCx, aArray.Obj()); 1.69 + 1.70 + // Throw if the wrong type of ArrayBufferView is passed in 1.71 + // (Part of the Web Crypto API spec) 1.72 + switch (JS_GetArrayBufferViewType(view)) { 1.73 + case TYPE_INT8: 1.74 + case TYPE_UINT8: 1.75 + case TYPE_UINT8_CLAMPED: 1.76 + case TYPE_INT16: 1.77 + case TYPE_UINT16: 1.78 + case TYPE_INT32: 1.79 + case TYPE_UINT32: 1.80 + break; 1.81 + default: 1.82 + aRv.Throw(NS_ERROR_DOM_TYPE_MISMATCH_ERR); 1.83 + return; 1.84 + } 1.85 + 1.86 + aArray.ComputeLengthAndData(); 1.87 + uint32_t dataLen = aArray.Length(); 1.88 + if (dataLen == 0) { 1.89 + NS_WARNING("ArrayBufferView length is 0, cannot continue"); 1.90 + aRetval.set(view); 1.91 + return; 1.92 + } else if (dataLen > 65536) { 1.93 + aRv.Throw(NS_ERROR_DOM_QUOTA_EXCEEDED_ERR); 1.94 + return; 1.95 + } 1.96 + 1.97 + uint8_t* data = aArray.Data(); 1.98 + 1.99 + if (XRE_GetProcessType() != GeckoProcessType_Default) { 1.100 + InfallibleTArray<uint8_t> randomValues; 1.101 + // Tell the parent process to generate random values via PContent 1.102 + ContentChild* cc = ContentChild::GetSingleton(); 1.103 + if (!cc->SendGetRandomValues(dataLen, &randomValues) || 1.104 + randomValues.Length() == 0) { 1.105 + aRv.Throw(NS_ERROR_FAILURE); 1.106 + return; 1.107 + } 1.108 + NS_ASSERTION(dataLen == randomValues.Length(), 1.109 + "Invalid length returned from parent process!"); 1.110 + memcpy(data, randomValues.Elements(), dataLen); 1.111 + } else { 1.112 + uint8_t *buf = GetRandomValues(dataLen); 1.113 + 1.114 + if (!buf) { 1.115 + aRv.Throw(NS_ERROR_FAILURE); 1.116 + return; 1.117 + } 1.118 + 1.119 + memcpy(data, buf, dataLen); 1.120 + NS_Free(buf); 1.121 + } 1.122 + 1.123 + aRetval.set(view); 1.124 +} 1.125 + 1.126 +#ifndef MOZ_DISABLE_CRYPTOLEGACY 1.127 +// Stub out the legacy nsIDOMCrypto methods. The actual 1.128 +// implementations are in security/manager/ssl/src/nsCrypto.{cpp,h} 1.129 + 1.130 +NS_IMETHODIMP 1.131 +Crypto::GetEnableSmartCardEvents(bool *aEnableSmartCardEvents) 1.132 +{ 1.133 + return NS_ERROR_NOT_IMPLEMENTED; 1.134 +} 1.135 + 1.136 +NS_IMETHODIMP 1.137 +Crypto::SetEnableSmartCardEvents(bool aEnableSmartCardEvents) 1.138 +{ 1.139 + return NS_ERROR_NOT_IMPLEMENTED; 1.140 +} 1.141 + 1.142 +bool 1.143 +Crypto::EnableSmartCardEvents() 1.144 +{ 1.145 + return false; 1.146 +} 1.147 + 1.148 +void 1.149 +Crypto::SetEnableSmartCardEvents(bool aEnable, ErrorResult& aRv) 1.150 +{ 1.151 + aRv.Throw(NS_ERROR_NOT_IMPLEMENTED); 1.152 +} 1.153 + 1.154 +void 1.155 +Crypto::GetVersion(nsString& aVersion) 1.156 +{ 1.157 +} 1.158 + 1.159 +mozilla::dom::CRMFObject* 1.160 +Crypto::GenerateCRMFRequest(JSContext* aContext, 1.161 + const nsCString& aReqDN, 1.162 + const nsCString& aRegToken, 1.163 + const nsCString& aAuthenticator, 1.164 + const nsCString& aEaCert, 1.165 + const nsCString& aJsCallback, 1.166 + const Sequence<JS::Value>& aArgs, 1.167 + ErrorResult& aRv) 1.168 +{ 1.169 + aRv.Throw(NS_ERROR_NOT_IMPLEMENTED); 1.170 + return nullptr; 1.171 +} 1.172 + 1.173 +void 1.174 +Crypto::ImportUserCertificates(const nsAString& aNickname, 1.175 + const nsAString& aCmmfResponse, 1.176 + bool aDoForcedBackup, 1.177 + nsAString& aReturn, 1.178 + ErrorResult& aRv) 1.179 +{ 1.180 + aRv.Throw(NS_ERROR_NOT_IMPLEMENTED); 1.181 +} 1.182 + 1.183 +void 1.184 +Crypto::SignText(JSContext* aContext, 1.185 + const nsAString& aStringToSign, 1.186 + const nsAString& aCaOption, 1.187 + const Sequence<nsCString>& aArgs, 1.188 + nsAString& aReturn) 1.189 + 1.190 +{ 1.191 + aReturn.AssignLiteral("error:internalError"); 1.192 +} 1.193 + 1.194 +void 1.195 +Crypto::Logout(ErrorResult& aRv) 1.196 +{ 1.197 + aRv.Throw(NS_ERROR_NOT_IMPLEMENTED); 1.198 +} 1.199 + 1.200 +#endif 1.201 + 1.202 +/* static */ uint8_t* 1.203 +Crypto::GetRandomValues(uint32_t aLength) 1.204 +{ 1.205 + nsCOMPtr<nsIRandomGenerator> randomGenerator; 1.206 + nsresult rv; 1.207 + randomGenerator = do_GetService("@mozilla.org/security/random-generator;1"); 1.208 + NS_ENSURE_TRUE(randomGenerator, nullptr); 1.209 + 1.210 + uint8_t* buf; 1.211 + rv = randomGenerator->GenerateRandomBytes(aLength, &buf); 1.212 + 1.213 + NS_ENSURE_SUCCESS(rv, nullptr); 1.214 + 1.215 + return buf; 1.216 +} 1.217 + 1.218 +} // namespace dom 1.219 +} // namespace mozilla