Bug 1350254 part 8. Switch CryptoKey to [Serializable]. r=baku

The spec doesn't say to do this, but I think we should.  See
https://github.com/w3c/webcrypto/issues/222

Differential Revision: https://phabricator.services.mozilla.com/D35722

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Boris Zbarsky 2019-06-25 06:48:41 +00:00
Родитель a136313b5e
Коммит 4b183f77b2
5 изменённых файлов: 31 добавлений и 40 удалений

Просмотреть файл

@ -10,7 +10,6 @@
#include "mozilla/AutoRestore.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/BlobBinding.h"
#include "mozilla/dom/CryptoKey.h"
#include "mozilla/dom/StructuredCloneBlob.h"
#include "mozilla/dom/Directory.h"
#include "mozilla/dom/DirectoryBinding.h"
@ -28,11 +27,9 @@
#include "mozilla/dom/StructuredCloneTags.h"
#include "mozilla/dom/StructuredCloneTester.h"
#include "mozilla/dom/StructuredCloneTesterBinding.h"
#include "mozilla/dom/SubtleCryptoBinding.h"
#include "mozilla/dom/ToJSValue.h"
#include "mozilla/dom/URLSearchParams.h"
#include "mozilla/dom/URLSearchParamsBinding.h"
#include "mozilla/dom/WebCryptoCommon.h"
#include "mozilla/dom/WebIDLSerializable.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/ipc/BackgroundChild.h"
@ -123,7 +120,7 @@ void AssertTagValues() {
static_assert(SCTAG_DOM_IMAGEDATA == 0xffff8007 &&
SCTAG_DOM_DOMPOINT == 0xffff8008 &&
SCTAG_DOM_DOMPOINTREADONLY == 0xffff8009 &&
SCTAG_DOM_WEBCRYPTO_KEY == 0xffff800a &&
SCTAG_DOM_CRYPTOKEY == 0xffff800a &&
SCTAG_DOM_NULL_PRINCIPAL == 0xffff800b &&
SCTAG_DOM_SYSTEM_PRINCIPAL == 0xffff800c &&
SCTAG_DOM_CONTENT_PRINCIPAL == 0xffff800d &&
@ -351,18 +348,11 @@ JSObject* StructuredCloneHolder::ReadFullySerializableObjects(
return deserializer(aCx, global, aReader);
}
if (aTag == SCTAG_DOM_WEBCRYPTO_KEY || aTag == SCTAG_DOM_URLSEARCHPARAMS) {
if (aTag == SCTAG_DOM_URLSEARCHPARAMS) {
// Prevent the return value from being trashed by a GC during ~nsRefPtr.
JS::Rooted<JSObject*> result(aCx);
{
if (aTag == SCTAG_DOM_WEBCRYPTO_KEY) {
RefPtr<CryptoKey> key = new CryptoKey(global);
if (!key->ReadStructuredClone(aReader)) {
result = nullptr;
} else {
result = key->WrapObject(aCx, nullptr);
}
} else if (aTag == SCTAG_DOM_URLSEARCHPARAMS) {
if (aTag == SCTAG_DOM_URLSEARCHPARAMS) {
RefPtr<URLSearchParams> usp = new URLSearchParams(global);
if (!usp->ReadStructuredClone(aReader)) {
result = nullptr;
@ -459,15 +449,6 @@ bool StructuredCloneHolder::WriteFullySerializableObjects(
}
}
// Handle Key cloning
{
CryptoKey* key = nullptr;
if (NS_SUCCEEDED(UNWRAP_OBJECT(CryptoKey, &obj, key))) {
return JS_WriteUint32Pair(aWriter, SCTAG_DOM_WEBCRYPTO_KEY, 0) &&
key->WriteStructuredClone(aWriter);
}
}
#ifdef MOZ_WEBRTC
{
// Handle WebRTC Certificate cloning

Просмотреть файл

@ -51,7 +51,7 @@ enum StructuredCloneTags {
// IMPORTANT: Don't change the order of these enum values. You could break
// IDB.
// This tag is for WebCrypto keys
SCTAG_DOM_WEBCRYPTO_KEY,
SCTAG_DOM_CRYPTOKEY,
// IMPORTANT: Don't change the order of these enum values. You could break
// IDB.

Просмотреть файл

@ -1138,7 +1138,8 @@ bool CryptoKey::PublicKeyValid(SECKEYPublicKey* aPubKey) {
return (rv == SECSuccess);
}
bool CryptoKey::WriteStructuredClone(JSStructuredCloneWriter* aWriter) const {
bool CryptoKey::WriteStructuredClone(JSContext* aCX,
JSStructuredCloneWriter* aWriter) const {
// Write in five pieces
// 1. Attributes
// 2. Symmetric key as raw (if present)
@ -1164,42 +1165,47 @@ bool CryptoKey::WriteStructuredClone(JSStructuredCloneWriter* aWriter) const {
WriteBuffer(aWriter, pub) && mAlgorithm.WriteStructuredClone(aWriter);
}
bool CryptoKey::ReadStructuredClone(JSStructuredCloneReader* aReader) {
// static
already_AddRefed<CryptoKey> CryptoKey::ReadStructuredClone(
JSContext* aCx, nsIGlobalObject* aGlobal,
JSStructuredCloneReader* aReader) {
// Ensure that NSS is initialized.
if (!EnsureNSSInitializedChromeOrContent()) {
return false;
return nullptr;
}
RefPtr<CryptoKey> key = new CryptoKey(aGlobal);
uint32_t version;
CryptoBuffer sym, priv, pub;
bool read = JS_ReadUint32Pair(aReader, &mAttributes, &version) &&
bool read = JS_ReadUint32Pair(aReader, &key->mAttributes, &version) &&
(version == CRYPTOKEY_SC_VERSION) && ReadBuffer(aReader, sym) &&
ReadBuffer(aReader, priv) && ReadBuffer(aReader, pub) &&
mAlgorithm.ReadStructuredClone(aReader);
key->mAlgorithm.ReadStructuredClone(aReader);
if (!read) {
return false;
return nullptr;
}
if (sym.Length() > 0 && !mSymKey.Assign(sym)) {
return false;
if (sym.Length() > 0 && !key->mSymKey.Assign(sym)) {
return nullptr;
}
if (priv.Length() > 0) {
mPrivateKey = CryptoKey::PrivateKeyFromPkcs8(priv);
key->mPrivateKey = CryptoKey::PrivateKeyFromPkcs8(priv);
}
if (pub.Length() > 0) {
mPublicKey = CryptoKey::PublicKeyFromSpki(pub);
key->mPublicKey = CryptoKey::PublicKeyFromSpki(pub);
}
// Ensure that what we've read is consistent
// If the attributes indicate a key type, should have a key of that type
if (!((GetKeyType() == SECRET && mSymKey.Length() > 0) ||
(GetKeyType() == PRIVATE && mPrivateKey) ||
(GetKeyType() == PUBLIC && mPublicKey))) {
return false;
if (!((key->GetKeyType() == SECRET && key->mSymKey.Length() > 0) ||
(key->GetKeyType() == PRIVATE && key->mPrivateKey) ||
(key->GetKeyType() == PUBLIC && key->mPublicKey))) {
return nullptr;
}
return true;
return key.forget();
}
} // namespace dom

Просмотреть файл

@ -164,8 +164,11 @@ class CryptoKey final : public nsISupports, public nsWrapperCache {
static bool PublicKeyValid(SECKEYPublicKey* aPubKey);
// Structured clone methods use these to clone keys
bool WriteStructuredClone(JSStructuredCloneWriter* aWriter) const;
bool ReadStructuredClone(JSStructuredCloneReader* aReader);
bool WriteStructuredClone(JSContext* aCx,
JSStructuredCloneWriter* aWriter) const;
static already_AddRefed<CryptoKey> ReadStructuredClone(
JSContext* aCx, nsIGlobalObject* aGlobal,
JSStructuredCloneReader* aReader);
private:
~CryptoKey() {}

Просмотреть файл

@ -152,6 +152,7 @@ dictionary JsonWebKey {
/***** The Main API *****/
[Serializable]
interface CryptoKey {
readonly attribute KeyType type;
readonly attribute boolean extractable;