Bug 1037892 - Implement changes to WebCrypto API from latest Editor's Draft r=bz,ttaubert

This commit is contained in:
Richard Barnes 2014-09-27 14:22:57 -04:00
Родитель 952cae1846
Коммит 63afe24da8
33 изменённых файлов: 889 добавлений и 1562 удалений

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

@ -1,82 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/AesKeyAlgorithm.h"
#include "mozilla/dom/SubtleCryptoBinding.h"
#include "mozilla/dom/WebCryptoCommon.h"
namespace mozilla {
namespace dom {
JSObject*
AesKeyAlgorithm::WrapObject(JSContext* aCx)
{
return AesKeyAlgorithmBinding::Wrap(aCx, this);
}
nsString
AesKeyAlgorithm::ToJwkAlg() const
{
if (mName.EqualsLiteral(WEBCRYPTO_ALG_AES_CBC)) {
switch (mLength) {
case 128: return NS_LITERAL_STRING(JWK_ALG_A128CBC);
case 192: return NS_LITERAL_STRING(JWK_ALG_A192CBC);
case 256: return NS_LITERAL_STRING(JWK_ALG_A256CBC);
}
}
if (mName.EqualsLiteral(WEBCRYPTO_ALG_AES_CTR)) {
switch (mLength) {
case 128: return NS_LITERAL_STRING(JWK_ALG_A128CTR);
case 192: return NS_LITERAL_STRING(JWK_ALG_A192CTR);
case 256: return NS_LITERAL_STRING(JWK_ALG_A256CTR);
}
}
if (mName.EqualsLiteral(WEBCRYPTO_ALG_AES_GCM)) {
switch (mLength) {
case 128: return NS_LITERAL_STRING(JWK_ALG_A128GCM);
case 192: return NS_LITERAL_STRING(JWK_ALG_A192GCM);
case 256: return NS_LITERAL_STRING(JWK_ALG_A256GCM);
}
}
if (mName.EqualsLiteral(WEBCRYPTO_ALG_AES_KW)) {
switch (mLength) {
case 128: return NS_LITERAL_STRING(JWK_ALG_A128KW);
case 192: return NS_LITERAL_STRING(JWK_ALG_A192KW);
case 256: return NS_LITERAL_STRING(JWK_ALG_A256KW);
}
}
return nsString();
}
bool
AesKeyAlgorithm::WriteStructuredClone(JSStructuredCloneWriter* aWriter) const
{
return JS_WriteUint32Pair(aWriter, SCTAG_AESKEYALG, 0) &&
JS_WriteUint32Pair(aWriter, mLength, 0) &&
WriteString(aWriter, mName);
}
KeyAlgorithm*
AesKeyAlgorithm::Create(nsIGlobalObject* aGlobal, JSStructuredCloneReader* aReader)
{
uint32_t length, zero;
nsString name;
bool read = JS_ReadUint32Pair(aReader, &length, &zero) &&
ReadString(aReader, name);
if (!read) {
return nullptr;
}
return new AesKeyAlgorithm(aGlobal, name, length);
}
} // namespace dom
} // namespace mozilla

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

@ -1,38 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_AesKeyAlgorithm_h
#define mozilla_dom_AesKeyAlgorithm_h
#include "mozilla/dom/BasicSymmetricKeyAlgorithm.h"
#include "js/TypeDecls.h"
namespace mozilla {
namespace dom {
class AesKeyAlgorithm MOZ_FINAL : public BasicSymmetricKeyAlgorithm
{
public:
AesKeyAlgorithm(nsIGlobalObject* aGlobal, const nsString& aName, uint16_t aLength)
: BasicSymmetricKeyAlgorithm(aGlobal, aName, aLength)
{}
~AesKeyAlgorithm()
{}
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
virtual nsString ToJwkAlg() const MOZ_OVERRIDE;
virtual bool WriteStructuredClone(JSStructuredCloneWriter* aWriter) const MOZ_OVERRIDE;
static KeyAlgorithm* Create(nsIGlobalObject* aGlobal,
JSStructuredCloneReader* aReader);
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_AesKeyAlgorithm_h

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

@ -1,38 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_BasicSymmetricKeyAlgorithm_h
#define mozilla_dom_BasicSymmetricKeyAlgorithm_h
#include "mozilla/dom/KeyAlgorithm.h"
namespace mozilla {
namespace dom {
class BasicSymmetricKeyAlgorithm : public KeyAlgorithm
{
public:
BasicSymmetricKeyAlgorithm(nsIGlobalObject* aGlobal, const nsString& aName, uint16_t aLength)
: KeyAlgorithm(aGlobal, aName)
, mLength(aLength)
{}
~BasicSymmetricKeyAlgorithm()
{}
uint16_t Length() const
{
return mLength;
}
protected:
uint16_t mLength;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_BasicSymmetricKeyAlgorithm_h

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

@ -161,6 +161,13 @@ CryptoBuffer::ToSECItem() const
return item;
}
JSObject*
CryptoBuffer::ToUint8Array(JSContext* aCx) const
{
return Uint8Array::Create(aCx, Length(), Elements());
}
// "BigInt" comes from the WebCrypto spec
// ("unsigned long" isn't very "big", of course)
// Likewise, the spec calls for big-endian ints

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

@ -40,6 +40,7 @@ public:
nsresult FromJwkBase64(const nsString& aBase64);
nsresult ToJwkBase64(nsString& aBase64);
SECItem* ToSECItem() const;
JSObject* ToUint8Array(JSContext* aCx) const;
bool GetBigIntValue(unsigned long& aRetVal);
};

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

@ -10,11 +10,12 @@
#include "mozilla/dom/CryptoKey.h"
#include "mozilla/dom/WebCryptoCommon.h"
#include "mozilla/dom/SubtleCryptoBinding.h"
#include "mozilla/dom/ToJSValue.h"
namespace mozilla {
namespace dom {
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(CryptoKey, mGlobal, mAlgorithm)
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(CryptoKey, mGlobal)
NS_IMPL_CYCLE_COLLECTING_ADDREF(CryptoKey)
NS_IMPL_CYCLE_COLLECTING_RELEASE(CryptoKey)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CryptoKey)
@ -90,10 +91,35 @@ CryptoKey::Extractable() const
return (mAttributes & EXTRACTABLE);
}
KeyAlgorithm*
CryptoKey::Algorithm() const
void
CryptoKey::GetAlgorithm(JSContext* cx, JS::MutableHandle<JSObject*> aRetVal,
ErrorResult& aRv) const
{
return mAlgorithm;
bool converted = false;
JS::RootedValue val(cx);
switch (mAlgorithm.mType) {
case KeyAlgorithmProxy::AES:
converted = ToJSValue(cx, mAlgorithm.mAes, &val);
break;
case KeyAlgorithmProxy::HMAC:
converted = ToJSValue(cx, mAlgorithm.mHmac, &val);
break;
case KeyAlgorithmProxy::RSA: {
RootedDictionary<RsaHashedKeyAlgorithm> rsa(cx);
mAlgorithm.mRsa.ToKeyAlgorithm(cx, rsa);
converted = ToJSValue(cx, rsa, &val);
break;
}
case KeyAlgorithmProxy::EC:
converted = ToJSValue(cx, mAlgorithm.mEc, &val);
break;
}
if (!converted) {
aRv.Throw(NS_ERROR_DOM_OPERATION_ERR);
return;
}
aRetVal.set(&val.toObject());
}
void
@ -125,6 +151,18 @@ CryptoKey::GetUsages(nsTArray<nsString>& aRetVal) const
}
}
KeyAlgorithmProxy&
CryptoKey::Algorithm()
{
return mAlgorithm;
}
const KeyAlgorithmProxy&
CryptoKey::Algorithm() const
{
return mAlgorithm;
}
CryptoKey::KeyType
CryptoKey::GetKeyType() const
{
@ -165,12 +203,6 @@ CryptoKey::SetExtractable(bool aExtractable)
}
}
void
CryptoKey::SetAlgorithm(KeyAlgorithm* aAlgorithm)
{
mAlgorithm = aAlgorithm;
}
void
CryptoKey::ClearUsages()
{
@ -205,6 +237,12 @@ CryptoKey::AddUsage(CryptoKey::KeyUsage aUsage)
mAttributes |= aUsage;
}
bool
CryptoKey::HasAnyUsage()
{
return !!(mAttributes & USAGES_MASK);
}
bool
CryptoKey::HasUsage(CryptoKey::KeyUsage aUsage)
{
@ -217,6 +255,25 @@ CryptoKey::HasUsageOtherThan(uint32_t aUsages)
return !!(mAttributes & USAGES_MASK & ~aUsages);
}
bool
CryptoKey::IsRecognizedUsage(const nsString& aUsage)
{
KeyUsage dummy;
nsresult rv = StringToUsage(aUsage, dummy);
return NS_SUCCEEDED(rv);
}
bool
CryptoKey::AllUsagesRecognized(const Sequence<nsString>& aUsages)
{
for (uint32_t i = 0; i < aUsages.Length(); ++i) {
if (!IsRecognizedUsage(aUsages[i])) {
return false;
}
}
return true;
}
void CryptoKey::SetSymKey(const CryptoBuffer& aSymKey)
{
mSymKey = aSymKey;
@ -441,14 +498,10 @@ SECKEYPrivateKey*
CryptoKey::PrivateKeyFromJwk(const JsonWebKey& aJwk,
const nsNSSShutDownPreventionLock& /*proofOfLock*/)
{
if (!aJwk.mKty.WasPassed()) {
return nullptr;
}
CK_OBJECT_CLASS privateKeyValue = CKO_PRIVATE_KEY;
CK_BBOOL falseValue = CK_FALSE;
if (aJwk.mKty.Value().EqualsLiteral(JWK_TYPE_EC)) {
if (aJwk.mKty.EqualsLiteral(JWK_TYPE_EC)) {
// Verify that all of the required parameters are present
CryptoBuffer x, y, d;
if (!aJwk.mCrv.WasPassed() ||
@ -459,7 +512,7 @@ CryptoKey::PrivateKeyFromJwk(const JsonWebKey& aJwk,
}
nsString namedCurve;
if (!NormalizeNamedCurveValue(aJwk.mCrv.Value(), namedCurve)) {
if (!NormalizeToken(aJwk.mCrv.Value(), namedCurve)) {
return nullptr;
}
@ -504,7 +557,7 @@ CryptoKey::PrivateKeyFromJwk(const JsonWebKey& aJwk,
PR_ARRAY_SIZE(keyTemplate));
}
if (aJwk.mKty.Value().EqualsLiteral(JWK_TYPE_RSA)) {
if (aJwk.mKty.EqualsLiteral(JWK_TYPE_RSA)) {
// Verify that all of the required parameters are present
CryptoBuffer n, e, d, p, q, dp, dq, qi;
if (!aJwk.mN.WasPassed() || NS_FAILED(n.FromJwkBase64(aJwk.mN.Value())) ||
@ -643,7 +696,7 @@ ECKeyToJwk(const PK11ObjectType aKeyType, void* aKey, const SECItem* aEcParams,
return false;
}
aRetVal.mKty.Construct(NS_LITERAL_STRING(JWK_TYPE_EC));
aRetVal.mKty = NS_LITERAL_STRING(JWK_TYPE_EC);
return true;
}
@ -674,7 +727,7 @@ CryptoKey::PrivateKeyToJwk(SECKEYPrivateKey* aPrivKey,
return NS_ERROR_DOM_OPERATION_ERR;
}
aRetVal.mKty.Construct(NS_LITERAL_STRING(JWK_TYPE_RSA));
aRetVal.mKty = NS_LITERAL_STRING(JWK_TYPE_RSA);
return NS_OK;
}
case ecKey: {
@ -716,11 +769,7 @@ SECKEYPublicKey*
CryptoKey::PublicKeyFromJwk(const JsonWebKey& aJwk,
const nsNSSShutDownPreventionLock& /*proofOfLock*/)
{
if (!aJwk.mKty.WasPassed()) {
return nullptr;
}
if (aJwk.mKty.Value().EqualsLiteral(JWK_TYPE_RSA)) {
if (aJwk.mKty.EqualsLiteral(JWK_TYPE_RSA)) {
// Verify that all of the required parameters are present
CryptoBuffer n, e;
if (!aJwk.mN.WasPassed() || NS_FAILED(n.FromJwkBase64(aJwk.mN.Value())) ||
@ -753,7 +802,7 @@ CryptoKey::PublicKeyFromJwk(const JsonWebKey& aJwk,
return SECKEY_ImportDERPublicKey(pkDer.get(), CKK_RSA);
}
if (aJwk.mKty.Value().EqualsLiteral(JWK_TYPE_EC)) {
if (aJwk.mKty.EqualsLiteral(JWK_TYPE_EC)) {
// Verify that all of the required parameters are present
CryptoBuffer x, y;
if (!aJwk.mCrv.WasPassed() ||
@ -777,7 +826,7 @@ CryptoKey::PublicKeyFromJwk(const JsonWebKey& aJwk,
key->pkcs11ID = CK_INVALID_HANDLE;
nsString namedCurve;
if (!NormalizeNamedCurveValue(aJwk.mCrv.Value(), namedCurve)) {
if (!NormalizeToken(aJwk.mCrv.Value(), namedCurve)) {
return nullptr;
}
@ -819,7 +868,7 @@ CryptoKey::PublicKeyToJwk(SECKEYPublicKey* aPubKey,
return NS_ERROR_DOM_OPERATION_ERR;
}
aRetVal.mKty.Construct(NS_LITERAL_STRING(JWK_TYPE_RSA));
aRetVal.mKty = NS_LITERAL_STRING(JWK_TYPE_RSA);
return NS_OK;
}
case ecKey:
@ -857,11 +906,11 @@ CryptoKey::WriteStructuredClone(JSStructuredCloneWriter* aWriter) const
CryptoKey::PublicKeyToSpki(mPublicKey, pub, locker);
}
return JS_WriteUint32Pair(aWriter, mAttributes, 0) &&
return JS_WriteUint32Pair(aWriter, mAttributes, CRYPTOKEY_SC_VERSION) &&
WriteBuffer(aWriter, mSymKey) &&
WriteBuffer(aWriter, priv) &&
WriteBuffer(aWriter, pub) &&
mAlgorithm->WriteStructuredClone(aWriter);
mAlgorithm.WriteStructuredClone(aWriter);
}
bool
@ -872,15 +921,15 @@ CryptoKey::ReadStructuredClone(JSStructuredCloneReader* aReader)
return false;
}
uint32_t zero;
uint32_t version;
CryptoBuffer sym, priv, pub;
nsRefPtr<KeyAlgorithm> algorithm;
bool read = JS_ReadUint32Pair(aReader, &mAttributes, &zero) &&
bool read = JS_ReadUint32Pair(aReader, &mAttributes, &version) &&
(version == CRYPTOKEY_SC_VERSION) &&
ReadBuffer(aReader, sym) &&
ReadBuffer(aReader, priv) &&
ReadBuffer(aReader, pub) &&
(algorithm = KeyAlgorithm::Create(mGlobal, aReader));
mAlgorithm.ReadStructuredClone(aReader);
if (!read) {
return false;
}
@ -894,7 +943,6 @@ CryptoKey::ReadStructuredClone(JSStructuredCloneReader* aReader)
if (pub.Length() > 0) {
mPublicKey = CryptoKey::PublicKeyFromSpki(pub, locker);
}
mAlgorithm = algorithm;
// Ensure that what we've read is consistent
// If the attributes indicate a key type, should have a key of that type

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

@ -14,11 +14,14 @@
#include "pk11pub.h"
#include "keyhi.h"
#include "ScopedNSSTypes.h"
#include "mozilla/dom/KeyAlgorithm.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/dom/CryptoBuffer.h"
#include "mozilla/dom/KeyAlgorithmProxy.h"
#include "js/StructuredClone.h"
#include "js/TypeDecls.h"
#define CRYPTOKEY_SC_VERSION 0x00000001
class nsIGlobalObject;
namespace mozilla {
@ -100,23 +103,28 @@ public:
// WebIDL methods
void GetType(nsString& aRetVal) const;
bool Extractable() const;
KeyAlgorithm* Algorithm() const;
void GetAlgorithm(JSContext* cx, JS::MutableHandle<JSObject*> aRetVal,
ErrorResult& aRv) const;
void GetUsages(nsTArray<nsString>& aRetVal) const;
// The below methods are not exposed to JS, but C++ can use
// them to manipulate the object
KeyAlgorithmProxy& Algorithm();
const KeyAlgorithmProxy& Algorithm() const;
KeyType GetKeyType() const;
nsresult SetType(const nsString& aType);
void SetType(KeyType aType);
void SetExtractable(bool aExtractable);
void SetAlgorithm(KeyAlgorithm* aAlgorithm);
void ClearUsages();
nsresult AddUsage(const nsString& aUsage);
nsresult AddUsageIntersecting(const nsString& aUsage, uint32_t aUsageMask);
void AddUsage(KeyUsage aUsage);
bool HasAnyUsage();
bool HasUsage(KeyUsage aUsage);
bool HasUsageOtherThan(uint32_t aUsages);
static bool IsRecognizedUsage(const nsString& aUsage);
static bool AllUsagesRecognized(const Sequence<nsString>& aUsages);
void SetSymKey(const CryptoBuffer& aSymKey);
void SetPrivateKey(SECKEYPrivateKey* aPrivateKey);
@ -172,7 +180,7 @@ private:
nsRefPtr<nsIGlobalObject> mGlobal;
uint32_t mAttributes; // see above
nsRefPtr<KeyAlgorithm> mAlgorithm;
KeyAlgorithmProxy mAlgorithm;
// Only one key handle should be set, according to the KeyType
CryptoBuffer mSymKey;

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

@ -1,31 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/CryptoKeyPair.h"
#include "mozilla/dom/SubtleCryptoBinding.h"
#include "nsContentUtils.h"
namespace mozilla {
namespace dom {
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(CryptoKeyPair, mGlobal, mPublicKey, mPrivateKey)
NS_IMPL_CYCLE_COLLECTING_ADDREF(CryptoKeyPair)
NS_IMPL_CYCLE_COLLECTING_RELEASE(CryptoKeyPair)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CryptoKeyPair)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
JSObject*
CryptoKeyPair::WrapObject(JSContext* aCx)
{
return CryptoKeyPairBinding::Wrap(aCx, this);
}
} // namespace dom
} // namespace mozilla

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

@ -1,63 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_CryptoKeyPair_h
#define mozilla_dom_CryptoKeyPair_h
#include "nsCycleCollectionParticipant.h"
#include "nsWrapperCache.h"
#include "nsIGlobalObject.h"
#include "mozilla/dom/CryptoKey.h"
#include "js/TypeDecls.h"
namespace mozilla {
namespace dom {
class CryptoKeyPair MOZ_FINAL : public nsISupports,
public nsWrapperCache
{
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(CryptoKeyPair)
public:
explicit CryptoKeyPair(nsIGlobalObject* aGlobal)
: mGlobal(aGlobal)
, mPublicKey(new CryptoKey(aGlobal))
, mPrivateKey(new CryptoKey(aGlobal))
{
SetIsDOMBinding();
}
nsIGlobalObject* GetParentObject() const
{
return mGlobal;
}
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
CryptoKey* PublicKey() const
{
return mPublicKey;
}
CryptoKey* PrivateKey() const
{
return mPrivateKey;
}
private:
~CryptoKeyPair() {}
nsRefPtr<nsIGlobalObject> mGlobal;
nsRefPtr<CryptoKey> mPublicKey;
nsRefPtr<CryptoKey> mPrivateKey;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_CryptoKeyPair_h

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

@ -1,43 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/EcKeyAlgorithm.h"
#include "mozilla/dom/SubtleCryptoBinding.h"
#include "mozilla/dom/WebCryptoCommon.h"
namespace mozilla {
namespace dom {
JSObject*
EcKeyAlgorithm::WrapObject(JSContext* aCx)
{
return EcKeyAlgorithmBinding::Wrap(aCx, this);
}
bool
EcKeyAlgorithm::WriteStructuredClone(JSStructuredCloneWriter* aWriter) const
{
return JS_WriteUint32Pair(aWriter, SCTAG_ECKEYALG, 0) &&
WriteString(aWriter, mNamedCurve) &&
WriteString(aWriter, mName);
}
KeyAlgorithm*
EcKeyAlgorithm::Create(nsIGlobalObject* aGlobal, JSStructuredCloneReader* aReader)
{
nsString name;
nsString namedCurve;
bool read = ReadString(aReader, namedCurve) &&
ReadString(aReader, name);
if (!read) {
return nullptr;
}
return new EcKeyAlgorithm(aGlobal, name, namedCurve);
}
} // namespace dom
} // namespace mozilla

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

@ -1,48 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_EcKeyAlgorithm_h
#define mozilla_dom_EcKeyAlgorithm_h
#include "mozilla/ErrorResult.h"
#include "mozilla/dom/KeyAlgorithm.h"
#include "js/TypeDecls.h"
namespace mozilla {
namespace dom {
class EcKeyAlgorithm : public KeyAlgorithm
{
public:
EcKeyAlgorithm(nsIGlobalObject* aGlobal,
const nsString& aName,
const nsString& aNamedCurve)
: KeyAlgorithm(aGlobal, aName)
, mNamedCurve(aNamedCurve)
{}
~EcKeyAlgorithm()
{}
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
void GetNamedCurve(nsString& aRetVal) const
{
aRetVal.Assign(mNamedCurve);
}
virtual bool WriteStructuredClone(JSStructuredCloneWriter* aWriter) const MOZ_OVERRIDE;
static KeyAlgorithm* Create(nsIGlobalObject* aGlobal,
JSStructuredCloneReader* aReader);
protected:
nsString mNamedCurve;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_EcKeyAlgorithm_h

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

@ -1,64 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/HmacKeyAlgorithm.h"
#include "mozilla/dom/SubtleCryptoBinding.h"
namespace mozilla {
namespace dom {
NS_IMPL_CYCLE_COLLECTION_INHERITED(HmacKeyAlgorithm, KeyAlgorithm, mHash)
NS_IMPL_ADDREF_INHERITED(HmacKeyAlgorithm, KeyAlgorithm)
NS_IMPL_RELEASE_INHERITED(HmacKeyAlgorithm, KeyAlgorithm)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(HmacKeyAlgorithm)
NS_INTERFACE_MAP_END_INHERITING(KeyAlgorithm)
JSObject*
HmacKeyAlgorithm::WrapObject(JSContext* aCx)
{
return HmacKeyAlgorithmBinding::Wrap(aCx, this);
}
nsString
HmacKeyAlgorithm::ToJwkAlg() const
{
switch (mMechanism) {
case CKM_SHA_1_HMAC: return NS_LITERAL_STRING(JWK_ALG_HS1);
case CKM_SHA256_HMAC: return NS_LITERAL_STRING(JWK_ALG_HS256);
case CKM_SHA384_HMAC: return NS_LITERAL_STRING(JWK_ALG_HS384);
case CKM_SHA512_HMAC: return NS_LITERAL_STRING(JWK_ALG_HS512);
}
return nsString();
}
bool
HmacKeyAlgorithm::WriteStructuredClone(JSStructuredCloneWriter* aWriter) const
{
nsString hashName;
mHash->GetName(hashName);
return JS_WriteUint32Pair(aWriter, SCTAG_HMACKEYALG, 0) &&
JS_WriteUint32Pair(aWriter, mLength, 0) &&
WriteString(aWriter, hashName) &&
WriteString(aWriter, mName);
}
KeyAlgorithm*
HmacKeyAlgorithm::Create(nsIGlobalObject* aGlobal, JSStructuredCloneReader* aReader)
{
uint32_t length, zero;
nsString hash, name;
bool read = JS_ReadUint32Pair(aReader, &length, &zero) &&
ReadString(aReader, hash) &&
ReadString(aReader, name);
if (!read) {
return nullptr;
}
return new HmacKeyAlgorithm(aGlobal, name, length, hash);
}
} // namespace dom
} // namespace mozilla

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

@ -1,72 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_HmacKeyAlgorithm_h
#define mozilla_dom_HmacKeyAlgorithm_h
#include "nsCycleCollectionParticipant.h"
#include "nsWrapperCache.h"
#include "nsAutoPtr.h"
#include "mozilla/dom/KeyAlgorithm.h"
#include "mozilla/dom/WebCryptoCommon.h"
#include "js/TypeDecls.h"
namespace mozilla {
namespace dom {
class HmacKeyAlgorithm MOZ_FINAL : public KeyAlgorithm
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HmacKeyAlgorithm, KeyAlgorithm)
HmacKeyAlgorithm(nsIGlobalObject* aGlobal,
const nsString& aName,
uint32_t aLength,
const nsString& aHash)
: KeyAlgorithm(aGlobal, aName)
, mHash(new KeyAlgorithm(aGlobal, aHash))
, mLength(aLength)
{
switch (mHash->Mechanism()) {
case CKM_SHA_1: mMechanism = CKM_SHA_1_HMAC; break;
case CKM_SHA256: mMechanism = CKM_SHA256_HMAC; break;
case CKM_SHA384: mMechanism = CKM_SHA384_HMAC; break;
case CKM_SHA512: mMechanism = CKM_SHA512_HMAC; break;
default: mMechanism = UNKNOWN_CK_MECHANISM; break;
}
}
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
KeyAlgorithm* Hash() const
{
return mHash;
}
uint32_t Length() const
{
return mLength;
}
virtual nsString ToJwkAlg() const MOZ_OVERRIDE;
virtual bool WriteStructuredClone(JSStructuredCloneWriter* aWriter) const MOZ_OVERRIDE;
static KeyAlgorithm* Create(nsIGlobalObject* aGlobal,
JSStructuredCloneReader* aReader);
protected:
~HmacKeyAlgorithm()
{}
nsRefPtr<KeyAlgorithm> mHash;
uint32_t mLength;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_HmacKeyAlgorithm_h

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

@ -1,116 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/KeyAlgorithm.h"
#include "mozilla/dom/WebCryptoCommon.h"
#include "mozilla/dom/AesKeyAlgorithm.h"
#include "mozilla/dom/EcKeyAlgorithm.h"
#include "mozilla/dom/HmacKeyAlgorithm.h"
#include "mozilla/dom/RsaKeyAlgorithm.h"
#include "mozilla/dom/RsaHashedKeyAlgorithm.h"
#include "mozilla/dom/SubtleCryptoBinding.h"
#include "mozilla/dom/WebCryptoCommon.h"
namespace mozilla {
namespace dom {
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(KeyAlgorithm, mGlobal)
NS_IMPL_CYCLE_COLLECTING_ADDREF(KeyAlgorithm)
NS_IMPL_CYCLE_COLLECTING_RELEASE(KeyAlgorithm)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(KeyAlgorithm)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
KeyAlgorithm::KeyAlgorithm(nsIGlobalObject* aGlobal, const nsString& aName)
: mGlobal(aGlobal)
, mName(aName)
{
SetIsDOMBinding();
// Set mechanism based on algorithm name
mMechanism = MapAlgorithmNameToMechanism(aName);
// HMAC not handled here, since it requires extra info
}
KeyAlgorithm::~KeyAlgorithm()
{
}
JSObject*
KeyAlgorithm::WrapObject(JSContext* aCx)
{
return KeyAlgorithmBinding::Wrap(aCx, this);
}
nsString
KeyAlgorithm::ToJwkAlg() const
{
return nsString();
}
void
KeyAlgorithm::GetName(nsString& aRetVal) const
{
aRetVal.Assign(mName);
}
bool
KeyAlgorithm::WriteStructuredClone(JSStructuredCloneWriter* aWriter) const
{
return WriteString(aWriter, mName);
}
KeyAlgorithm*
KeyAlgorithm::Create(nsIGlobalObject* aGlobal, JSStructuredCloneReader* aReader)
{
uint32_t tag, zero;
bool read = JS_ReadUint32Pair( aReader, &tag, &zero );
if (!read) {
return nullptr;
}
KeyAlgorithm* algorithm = nullptr;
switch (tag) {
case SCTAG_KEYALG: {
nsString name;
read = ReadString(aReader, name);
if (!read) {
return nullptr;
}
algorithm = new KeyAlgorithm(aGlobal, name);
break;
}
case SCTAG_AESKEYALG: {
algorithm = AesKeyAlgorithm::Create(aGlobal, aReader);
break;
}
case SCTAG_ECKEYALG: {
algorithm = EcKeyAlgorithm::Create(aGlobal, aReader);
break;
}
case SCTAG_HMACKEYALG: {
algorithm = HmacKeyAlgorithm::Create(aGlobal, aReader);
break;
}
case SCTAG_RSAKEYALG: {
algorithm = RsaKeyAlgorithm::Create(aGlobal, aReader);
break;
}
case SCTAG_RSAHASHEDKEYALG: {
algorithm = RsaHashedKeyAlgorithm::Create(aGlobal, aReader);
break;
}
// No default, algorithm is already nullptr
}
return algorithm;
}
} // namespace dom
} // namespace mozilla

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

@ -1,80 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_KeyAlgorithm_h
#define mozilla_dom_KeyAlgorithm_h
#include "nsCycleCollectionParticipant.h"
#include "nsIGlobalObject.h"
#include "nsWrapperCache.h"
#include "pk11pub.h"
#include "mozilla/dom/CryptoBuffer.h"
#include "js/StructuredClone.h"
#include "js/TypeDecls.h"
namespace mozilla {
namespace dom {
class CryptoKey;
class KeyAlgorithm;
enum KeyAlgorithmStructuredCloneTags {
SCTAG_KEYALG,
SCTAG_AESKEYALG,
SCTAG_ECKEYALG,
SCTAG_HMACKEYALG,
SCTAG_RSAKEYALG,
SCTAG_RSAHASHEDKEYALG
};
}
namespace dom {
class KeyAlgorithm : public nsISupports,
public nsWrapperCache
{
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(KeyAlgorithm)
public:
KeyAlgorithm(nsIGlobalObject* aGlobal, const nsString& aName);
nsIGlobalObject* GetParentObject() const
{
return mGlobal;
}
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
void GetName(nsString& aRetVal) const;
virtual nsString ToJwkAlg() const;
// Structured clone support methods
virtual bool WriteStructuredClone(JSStructuredCloneWriter* aWriter) const;
static KeyAlgorithm* Create(nsIGlobalObject* aGlobal,
JSStructuredCloneReader* aReader);
// Helper method to look up NSS methods
// Sub-classes should assign mMechanism on constructor
CK_MECHANISM_TYPE Mechanism() const {
return mMechanism;
}
protected:
virtual ~KeyAlgorithm();
nsRefPtr<nsIGlobalObject> mGlobal;
nsString mName;
CK_MECHANISM_TYPE mMechanism;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_KeyAlgorithm_h

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

@ -0,0 +1,215 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/KeyAlgorithmProxy.h"
#include "mozilla/dom/WebCryptoCommon.h"
namespace mozilla {
namespace dom {
bool
KeyAlgorithmProxy::WriteStructuredClone(JSStructuredCloneWriter* aWriter) const
{
if (!WriteString(aWriter, mName) ||
!JS_WriteUint32Pair(aWriter, mType, KEY_ALGORITHM_SC_VERSION)) {
return false;
}
switch (mType) {
case AES:
return JS_WriteUint32Pair(aWriter, mAes.mLength, 0);
case HMAC:
return JS_WriteUint32Pair(aWriter, mHmac.mLength, 0) &&
WriteString(aWriter, mHmac.mHash.mName);
case RSA: {
return JS_WriteUint32Pair(aWriter, mRsa.mModulusLength, 0) &&
WriteBuffer(aWriter, mRsa.mPublicExponent) &&
WriteString(aWriter, mRsa.mHash.mName);
}
case EC:
return WriteString(aWriter, mEc.mNamedCurve);
}
return false;
}
bool
KeyAlgorithmProxy::ReadStructuredClone(JSStructuredCloneReader* aReader)
{
uint32_t type, version, dummy;
if (!ReadString(aReader, mName) ||
!JS_ReadUint32Pair(aReader, &type, &version)) {
return false;
}
if (version != KEY_ALGORITHM_SC_VERSION) {
return false;
}
mType = (KeyAlgorithmType) type;
switch (mType) {
case AES: {
uint32_t length;
if (!JS_ReadUint32Pair(aReader, &length, &dummy)) {
return false;
}
mAes.mLength = length;
mAes.mName = mName;
return true;
}
case HMAC: {
if (!JS_ReadUint32Pair(aReader, &mHmac.mLength, &dummy) ||
!ReadString(aReader, mHmac.mHash.mName)) {
return false;
}
mHmac.mName = mName;
return true;
}
case RSA: {
uint32_t modulusLength;
nsString hashName;
if (!JS_ReadUint32Pair(aReader, &modulusLength, &dummy) ||
!ReadBuffer(aReader, mRsa.mPublicExponent) ||
!ReadString(aReader, mRsa.mHash.mName)) {
return false;
}
mRsa.mModulusLength = modulusLength;
mRsa.mName = mName;
return true;
}
case EC: {
nsString namedCurve;
if (!ReadString(aReader, mEc.mNamedCurve)) {
return false;
}
mEc.mName = mName;
return true;
}
}
return false;
}
CK_MECHANISM_TYPE
KeyAlgorithmProxy::Mechanism() const
{
if (mType == HMAC) {
return GetMechanism(mHmac);
}
return MapAlgorithmNameToMechanism(mName);
}
nsString
KeyAlgorithmProxy::JwkAlg() const
{
if (mName.EqualsLiteral(WEBCRYPTO_ALG_AES_CBC)) {
switch (mAes.mLength) {
case 128: return NS_LITERAL_STRING(JWK_ALG_A128CBC);
case 192: return NS_LITERAL_STRING(JWK_ALG_A192CBC);
case 256: return NS_LITERAL_STRING(JWK_ALG_A256CBC);
}
}
if (mName.EqualsLiteral(WEBCRYPTO_ALG_AES_CTR)) {
switch (mAes.mLength) {
case 128: return NS_LITERAL_STRING(JWK_ALG_A128CTR);
case 192: return NS_LITERAL_STRING(JWK_ALG_A192CTR);
case 256: return NS_LITERAL_STRING(JWK_ALG_A256CTR);
}
}
if (mName.EqualsLiteral(WEBCRYPTO_ALG_AES_GCM)) {
switch (mAes.mLength) {
case 128: return NS_LITERAL_STRING(JWK_ALG_A128GCM);
case 192: return NS_LITERAL_STRING(JWK_ALG_A192GCM);
case 256: return NS_LITERAL_STRING(JWK_ALG_A256GCM);
}
}
if (mName.EqualsLiteral(WEBCRYPTO_ALG_AES_KW)) {
switch (mAes.mLength) {
case 128: return NS_LITERAL_STRING(JWK_ALG_A128KW);
case 192: return NS_LITERAL_STRING(JWK_ALG_A192KW);
case 256: return NS_LITERAL_STRING(JWK_ALG_A256KW);
}
}
if (mName.EqualsLiteral(WEBCRYPTO_ALG_HMAC)) {
nsString hashName = mHmac.mHash.mName;
if (hashName.EqualsLiteral(WEBCRYPTO_ALG_SHA1)) {
return NS_LITERAL_STRING(JWK_ALG_HS1);
} else if (hashName.EqualsLiteral(WEBCRYPTO_ALG_SHA256)) {
return NS_LITERAL_STRING(JWK_ALG_HS256);
} else if (hashName.EqualsLiteral(WEBCRYPTO_ALG_SHA384)) {
return NS_LITERAL_STRING(JWK_ALG_HS384);
} else if (hashName.EqualsLiteral(WEBCRYPTO_ALG_SHA512)) {
return NS_LITERAL_STRING(JWK_ALG_HS512);
}
}
if (mName.EqualsLiteral(WEBCRYPTO_ALG_RSASSA_PKCS1)) {
nsString hashName = mRsa.mHash.mName;
if (hashName.EqualsLiteral(WEBCRYPTO_ALG_SHA1)) {
return NS_LITERAL_STRING(JWK_ALG_RS1);
} else if (hashName.EqualsLiteral(WEBCRYPTO_ALG_SHA256)) {
return NS_LITERAL_STRING(JWK_ALG_RS256);
} else if (hashName.EqualsLiteral(WEBCRYPTO_ALG_SHA384)) {
return NS_LITERAL_STRING(JWK_ALG_RS384);
} else if (hashName.EqualsLiteral(WEBCRYPTO_ALG_SHA512)) {
return NS_LITERAL_STRING(JWK_ALG_RS512);
}
}
if (mName.EqualsLiteral(WEBCRYPTO_ALG_RSA_OAEP)) {
nsString hashName = mRsa.mHash.mName;
if (hashName.EqualsLiteral(WEBCRYPTO_ALG_SHA1)) {
return NS_LITERAL_STRING(JWK_ALG_RSA_OAEP);
} else if (hashName.EqualsLiteral(WEBCRYPTO_ALG_SHA256)) {
return NS_LITERAL_STRING(JWK_ALG_RSA_OAEP_256);
} else if (hashName.EqualsLiteral(WEBCRYPTO_ALG_SHA384)) {
return NS_LITERAL_STRING(JWK_ALG_RSA_OAEP_384);
} else if (hashName.EqualsLiteral(WEBCRYPTO_ALG_SHA512)) {
return NS_LITERAL_STRING(JWK_ALG_RSA_OAEP_512);
}
}
return nsString();
}
CK_MECHANISM_TYPE
KeyAlgorithmProxy::GetMechanism(const KeyAlgorithm& aAlgorithm)
{
// For everything but HMAC, the name determines the mechanism
// HMAC is handled by the specialization below
return MapAlgorithmNameToMechanism(aAlgorithm.mName);
}
CK_MECHANISM_TYPE
KeyAlgorithmProxy::GetMechanism(const HmacKeyAlgorithm& aAlgorithm)
{
// The use of HmacKeyAlgorithm doesn't completely prevent this
// method from being called with dictionaries that don't really
// represent HMAC key algorithms.
MOZ_ASSERT(aAlgorithm.mName.EqualsLiteral(WEBCRYPTO_ALG_HMAC));
CK_MECHANISM_TYPE hashMech;
hashMech = MapAlgorithmNameToMechanism(aAlgorithm.mHash.mName);
switch (hashMech) {
case CKM_SHA_1: return CKM_SHA_1_HMAC;
case CKM_SHA256: return CKM_SHA256_HMAC;
case CKM_SHA384: return CKM_SHA384_HMAC;
case CKM_SHA512: return CKM_SHA512_HMAC;
}
return UNKNOWN_CK_MECHANISM;
}
} // namespace dom
} // namespace mozilla

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

@ -0,0 +1,117 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_KeyAlgorithmProxy_h
#define mozilla_dom_KeyAlgorithmProxy_h
#include "pk11pub.h"
#include "js/StructuredClone.h"
#include "mozilla/dom/KeyAlgorithmBinding.h"
#include "mozilla/dom/WebCryptoCommon.h"
#define KEY_ALGORITHM_SC_VERSION 0x00000001
namespace mozilla {
namespace dom {
// A heap-safe variant of RsaHashedKeyAlgorithm
// The only difference is that it uses CryptoBuffer instead of Uint8Array
struct RsaHashedKeyAlgorithmStorage {
nsString mName;
KeyAlgorithm mHash;
uint16_t mModulusLength;
CryptoBuffer mPublicExponent;
void
ToKeyAlgorithm(JSContext* aCx, RsaHashedKeyAlgorithm& aRsa) const
{
aRsa.mName = mName;
aRsa.mModulusLength = mModulusLength;
aRsa.mHash.mName = mHash.mName;
aRsa.mPublicExponent.Init(mPublicExponent.ToUint8Array(aCx));
aRsa.mPublicExponent.ComputeLengthAndData();
}
};
// This class encapuslates a KeyAlgorithm object, and adds several
// methods that make WebCrypto operations simpler.
struct KeyAlgorithmProxy
{
enum KeyAlgorithmType {
AES,
HMAC,
RSA,
EC
};
KeyAlgorithmType mType;
// Plain is always populated with the algorithm name
// Others are only populated for the corresponding key type
nsString mName;
AesKeyAlgorithm mAes;
HmacKeyAlgorithm mHmac;
RsaHashedKeyAlgorithmStorage mRsa;
EcKeyAlgorithm mEc;
// Structured clone
bool WriteStructuredClone(JSStructuredCloneWriter* aWriter) const;
bool ReadStructuredClone(JSStructuredCloneReader* aReader);
// Extract various forms of derived information
CK_MECHANISM_TYPE Mechanism() const;
nsString JwkAlg() const;
// And in static form for calling on raw KeyAlgorithm dictionaries
static CK_MECHANISM_TYPE GetMechanism(const KeyAlgorithm& aAlgorithm);
static CK_MECHANISM_TYPE GetMechanism(const HmacKeyAlgorithm& aAlgorithm);
static nsString GetJwkAlg(const KeyAlgorithm& aAlgorithm);
// Construction of the various algorithm types
void
MakeAes(const nsString& aName, uint32_t aLength)
{
mType = AES;
mName = aName;
mAes.mName = aName;
mAes.mLength = aLength;
}
void
MakeHmac(uint32_t aLength, const nsString& aHashName)
{
mType = HMAC;
mName = NS_LITERAL_STRING(WEBCRYPTO_ALG_HMAC);
mHmac.mName = NS_LITERAL_STRING(WEBCRYPTO_ALG_HMAC);
mHmac.mLength = aLength;
mHmac.mHash.mName = aHashName;
}
void
MakeRsa(const nsString& aName, uint32_t aModulusLength,
const CryptoBuffer& aPublicExponent, const nsString& aHashName)
{
mType = RSA;
mName = aName;
mRsa.mName = aName;
mRsa.mModulusLength = aModulusLength;
mRsa.mHash.mName = aHashName;
mRsa.mPublicExponent.Assign(aPublicExponent);
}
void
MakeEc(const nsString& aName, const nsString& aNamedCurve)
{
mType = EC;
mName = aName;
mEc.mName = aName;
mEc.mNamedCurve = aNamedCurve;
}
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_KeyAlgorithmProxy_h

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

@ -1,80 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/RsaHashedKeyAlgorithm.h"
#include "mozilla/dom/SubtleCryptoBinding.h"
#include "mozilla/dom/WebCryptoCommon.h"
namespace mozilla {
namespace dom {
NS_IMPL_CYCLE_COLLECTION_INHERITED(RsaHashedKeyAlgorithm, RsaKeyAlgorithm, mHash)
NS_IMPL_ADDREF_INHERITED(RsaHashedKeyAlgorithm, RsaKeyAlgorithm)
NS_IMPL_RELEASE_INHERITED(RsaHashedKeyAlgorithm, RsaKeyAlgorithm)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(RsaHashedKeyAlgorithm)
NS_INTERFACE_MAP_END_INHERITING(RsaKeyAlgorithm)
JSObject*
RsaHashedKeyAlgorithm::WrapObject(JSContext* aCx)
{
return RsaHashedKeyAlgorithmBinding::Wrap(aCx, this);
}
nsString
RsaHashedKeyAlgorithm::ToJwkAlg() const
{
if (mName.EqualsLiteral(WEBCRYPTO_ALG_RSASSA_PKCS1)) {
switch (mHash->Mechanism()) {
case CKM_SHA_1: return NS_LITERAL_STRING(JWK_ALG_RS1);
case CKM_SHA256: return NS_LITERAL_STRING(JWK_ALG_RS256);
case CKM_SHA384: return NS_LITERAL_STRING(JWK_ALG_RS384);
case CKM_SHA512: return NS_LITERAL_STRING(JWK_ALG_RS512);
}
}
if (mName.EqualsLiteral(WEBCRYPTO_ALG_RSA_OAEP)) {
switch(mHash->Mechanism()) {
case CKM_SHA_1: return NS_LITERAL_STRING(JWK_ALG_RSA_OAEP);
case CKM_SHA256: return NS_LITERAL_STRING(JWK_ALG_RSA_OAEP_256);
case CKM_SHA384: return NS_LITERAL_STRING(JWK_ALG_RSA_OAEP_256);
case CKM_SHA512: return NS_LITERAL_STRING(JWK_ALG_RSA_OAEP_512);
}
}
return nsString();
}
bool
RsaHashedKeyAlgorithm::WriteStructuredClone(JSStructuredCloneWriter* aWriter) const
{
nsString hashName;
mHash->GetName(hashName);
return JS_WriteUint32Pair(aWriter, SCTAG_RSAHASHEDKEYALG, 0) &&
JS_WriteUint32Pair(aWriter, mModulusLength, 0) &&
WriteBuffer(aWriter, mPublicExponent) &&
WriteString(aWriter, hashName) &&
WriteString(aWriter, mName);
}
KeyAlgorithm*
RsaHashedKeyAlgorithm::Create(nsIGlobalObject* aGlobal, JSStructuredCloneReader* aReader) {
uint32_t modulusLength, zero;
CryptoBuffer publicExponent;
nsString name, hash;
bool read = JS_ReadUint32Pair(aReader, &modulusLength, &zero) &&
ReadBuffer(aReader, publicExponent) &&
ReadString(aReader, hash) &&
ReadString(aReader, name);
if (!read) {
return nullptr;
}
return new RsaHashedKeyAlgorithm(aGlobal, name, modulusLength, publicExponent, hash);
}
} // namespace dom
} // namespace mozilla

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

@ -1,53 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_RsaHashedKeyAlgorithm_h
#define mozilla_dom_RsaHashedKeyAlgorithm_h
#include "nsAutoPtr.h"
#include "mozilla/dom/RsaKeyAlgorithm.h"
namespace mozilla {
namespace dom {
class RsaHashedKeyAlgorithm MOZ_FINAL : public RsaKeyAlgorithm
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(RsaHashedKeyAlgorithm, RsaKeyAlgorithm)
RsaHashedKeyAlgorithm(nsIGlobalObject* aGlobal,
const nsString& aName,
uint32_t aModulusLength,
const CryptoBuffer& aPublicExponent,
const nsString& aHashName)
: RsaKeyAlgorithm(aGlobal, aName, aModulusLength, aPublicExponent)
, mHash(new KeyAlgorithm(aGlobal, aHashName))
{}
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
virtual nsString ToJwkAlg() const MOZ_OVERRIDE;
KeyAlgorithm* Hash() const
{
return mHash;
}
virtual bool WriteStructuredClone(JSStructuredCloneWriter* aWriter) const MOZ_OVERRIDE;
static KeyAlgorithm* Create(nsIGlobalObject* aGlobal,
JSStructuredCloneReader* aReader);
private:
~RsaHashedKeyAlgorithm() {}
nsRefPtr<KeyAlgorithm> mHash;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_RsaHashedKeyAlgorithm_h

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

@ -1,46 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/RsaKeyAlgorithm.h"
#include "mozilla/dom/SubtleCryptoBinding.h"
#include "mozilla/dom/WebCryptoCommon.h"
namespace mozilla {
namespace dom {
JSObject*
RsaKeyAlgorithm::WrapObject(JSContext* aCx)
{
return RsaKeyAlgorithmBinding::Wrap(aCx, this);
}
bool
RsaKeyAlgorithm::WriteStructuredClone(JSStructuredCloneWriter* aWriter) const
{
return JS_WriteUint32Pair(aWriter, SCTAG_RSAKEYALG, 0) &&
JS_WriteUint32Pair(aWriter, mModulusLength, 0) &&
WriteBuffer(aWriter, mPublicExponent) &&
WriteString(aWriter, mName);
}
KeyAlgorithm*
RsaKeyAlgorithm::Create(nsIGlobalObject* aGlobal, JSStructuredCloneReader* aReader)
{
uint32_t modulusLength, zero;
CryptoBuffer publicExponent;
nsString name;
bool read = JS_ReadUint32Pair(aReader, &modulusLength, &zero) &&
ReadBuffer(aReader, publicExponent) &&
ReadString(aReader, name);
if (!read) {
return nullptr;
}
return new RsaKeyAlgorithm(aGlobal, name, modulusLength, publicExponent);
}
} // namespace dom
} // namespace mozilla

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

@ -1,63 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_RsaKeyAlgorithm_h
#define mozilla_dom_RsaKeyAlgorithm_h
#include "mozilla/ErrorResult.h"
#include "mozilla/dom/KeyAlgorithm.h"
#include "js/TypeDecls.h"
namespace mozilla {
namespace dom {
class RsaKeyAlgorithm : public KeyAlgorithm
{
public:
RsaKeyAlgorithm(nsIGlobalObject* aGlobal,
const nsString& aName,
uint32_t aModulusLength,
const CryptoBuffer& aPublicExponent)
: KeyAlgorithm(aGlobal, aName)
, mModulusLength(aModulusLength)
, mPublicExponent(aPublicExponent)
{}
~RsaKeyAlgorithm()
{}
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
uint32_t ModulusLength() const
{
return mModulusLength;
}
void GetPublicExponent(JSContext* cx, JS::MutableHandle<JSObject*> aRetval,
ErrorResult& aError) const
{
TypedArrayCreator<Uint8Array> creator(mPublicExponent);
JSObject* retval = creator.Create(cx);
if (!retval) {
aError.Throw(NS_ERROR_OUT_OF_MEMORY);
} else {
aRetval.set(retval);
}
}
virtual bool WriteStructuredClone(JSStructuredCloneWriter* aWriter) const MOZ_OVERRIDE;
static KeyAlgorithm* Create(nsIGlobalObject* aGlobal,
JSStructuredCloneReader* aReader);
protected:
uint32_t mModulusLength;
CryptoBuffer mPublicExponent;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_RsaKeyAlgorithm_h

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

@ -9,6 +9,7 @@
#include "pk11pub.h"
#include "nsString.h"
#include "nsContentUtils.h"
#include "mozilla/dom/CryptoBuffer.h"
#include "js/StructuredClone.h"
@ -23,7 +24,6 @@
#define WEBCRYPTO_ALG_SHA512 "SHA-512"
#define WEBCRYPTO_ALG_HMAC "HMAC"
#define WEBCRYPTO_ALG_PBKDF2 "PBKDF2"
#define WEBCRYPTO_ALG_RSAES_PKCS1 "RSAES-PKCS1-v1_5"
#define WEBCRYPTO_ALG_RSASSA_PKCS1 "RSASSA-PKCS1-v1_5"
#define WEBCRYPTO_ALG_RSA_OAEP "RSA-OAEP"
#define WEBCRYPTO_ALG_ECDH "ECDH"
@ -181,8 +181,6 @@ MapAlgorithmNameToMechanism(const nsString& aName)
mechanism = CKM_SHA512;
} else if (aName.EqualsLiteral(WEBCRYPTO_ALG_PBKDF2)) {
mechanism = CKM_PKCS5_PBKD2;
} else if (aName.EqualsLiteral(WEBCRYPTO_ALG_RSAES_PKCS1)) {
mechanism = CKM_RSA_PKCS;
} else if (aName.EqualsLiteral(WEBCRYPTO_ALG_RSASSA_PKCS1)) {
mechanism = CKM_RSA_PKCS;
} else if (aName.EqualsLiteral(WEBCRYPTO_ALG_RSA_OAEP)) {
@ -194,14 +192,45 @@ MapAlgorithmNameToMechanism(const nsString& aName)
return mechanism;
}
#define NORMALIZED_EQUALS(aTest, aConst) \
nsContentUtils::EqualsIgnoreASCIICase(aTest, NS_LITERAL_STRING(aConst))
inline bool
NormalizeNamedCurveValue(const nsString& aNamedCurve, nsString& aDest)
NormalizeToken(const nsString& aName, nsString& aDest)
{
if (aNamedCurve.EqualsIgnoreCase(WEBCRYPTO_NAMED_CURVE_P256)) {
// Algorithm names
if (NORMALIZED_EQUALS(aName, WEBCRYPTO_ALG_AES_CBC)) {
aDest.AssignLiteral(WEBCRYPTO_ALG_AES_CBC);
} else if (NORMALIZED_EQUALS(aName, WEBCRYPTO_ALG_AES_CTR)) {
aDest.AssignLiteral(WEBCRYPTO_ALG_AES_CTR);
} else if (NORMALIZED_EQUALS(aName, WEBCRYPTO_ALG_AES_GCM)) {
aDest.AssignLiteral(WEBCRYPTO_ALG_AES_GCM);
} else if (NORMALIZED_EQUALS(aName, WEBCRYPTO_ALG_AES_KW)) {
aDest.AssignLiteral(WEBCRYPTO_ALG_AES_KW);
} else if (NORMALIZED_EQUALS(aName, WEBCRYPTO_ALG_SHA1)) {
aDest.AssignLiteral(WEBCRYPTO_ALG_SHA1);
} else if (NORMALIZED_EQUALS(aName, WEBCRYPTO_ALG_SHA256)) {
aDest.AssignLiteral(WEBCRYPTO_ALG_SHA256);
} else if (NORMALIZED_EQUALS(aName, WEBCRYPTO_ALG_SHA384)) {
aDest.AssignLiteral(WEBCRYPTO_ALG_SHA384);
} else if (NORMALIZED_EQUALS(aName, WEBCRYPTO_ALG_SHA512)) {
aDest.AssignLiteral(WEBCRYPTO_ALG_SHA512);
} else if (NORMALIZED_EQUALS(aName, WEBCRYPTO_ALG_HMAC)) {
aDest.AssignLiteral(WEBCRYPTO_ALG_HMAC);
} else if (NORMALIZED_EQUALS(aName, WEBCRYPTO_ALG_PBKDF2)) {
aDest.AssignLiteral(WEBCRYPTO_ALG_PBKDF2);
} else if (NORMALIZED_EQUALS(aName, WEBCRYPTO_ALG_RSASSA_PKCS1)) {
aDest.AssignLiteral(WEBCRYPTO_ALG_RSASSA_PKCS1);
} else if (NORMALIZED_EQUALS(aName, WEBCRYPTO_ALG_RSA_OAEP)) {
aDest.AssignLiteral(WEBCRYPTO_ALG_RSA_OAEP);
} else if (NORMALIZED_EQUALS(aName, WEBCRYPTO_ALG_ECDH)) {
aDest.AssignLiteral(WEBCRYPTO_ALG_ECDH);
// Named curve values
} else if (NORMALIZED_EQUALS(aName, WEBCRYPTO_NAMED_CURVE_P256)) {
aDest.AssignLiteral(WEBCRYPTO_NAMED_CURVE_P256);
} else if (aNamedCurve.EqualsIgnoreCase(WEBCRYPTO_NAMED_CURVE_P384)) {
} else if (NORMALIZED_EQUALS(aName, WEBCRYPTO_NAMED_CURVE_P384)) {
aDest.AssignLiteral(WEBCRYPTO_NAMED_CURVE_P384);
} else if (aNamedCurve.EqualsIgnoreCase(WEBCRYPTO_NAMED_CURVE_P521)) {
} else if (NORMALIZED_EQUALS(aName, WEBCRYPTO_NAMED_CURVE_P521)) {
aDest.AssignLiteral(WEBCRYPTO_NAMED_CURVE_P521);
} else {
return false;

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -5,30 +5,17 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
EXPORTS.mozilla.dom += [
'AesKeyAlgorithm.h',
'BasicSymmetricKeyAlgorithm.h',
'CryptoBuffer.h',
'CryptoKey.h',
'CryptoKeyPair.h',
'EcKeyAlgorithm.h',
'HmacKeyAlgorithm.h',
'KeyAlgorithm.h',
'RsaHashedKeyAlgorithm.h',
'RsaKeyAlgorithm.h',
'KeyAlgorithmProxy.h',
'WebCryptoCommon.h',
'WebCryptoTask.h',
]
UNIFIED_SOURCES += [
'AesKeyAlgorithm.cpp',
'CryptoBuffer.cpp',
'CryptoKey.cpp',
'CryptoKeyPair.cpp',
'EcKeyAlgorithm.cpp',
'HmacKeyAlgorithm.cpp',
'KeyAlgorithm.cpp',
'RsaHashedKeyAlgorithm.cpp',
'RsaKeyAlgorithm.cpp',
'KeyAlgorithmProxy.cpp',
'WebCryptoTask.cpp',
]

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

@ -71,7 +71,6 @@ TestArray.addTest(
function doExport(x) {
if (!hasKeyFields(x)) {
window.result = x;
throw "Invalid key; missing field(s)";
} else if ((x.algorithm.name != alg) ||
(x.algorithm.length != 8 * tv.raw.length) ||
@ -85,7 +84,7 @@ TestArray.addTest(
}
crypto.subtle.importKey("raw", tv.raw, alg, true, ["encrypt"])
.then(doExport, error(that))
.then(doExport)
.then(
memcmp_complete(that, tv.raw),
error(that)
@ -153,7 +152,7 @@ TestArray.addTest(
}
crypto.subtle.importKey("pkcs8", tv.pkcs8, alg, true, ["sign"])
.then(doExport, error(that))
.then(doExport)
.then(
memcmp_complete(that, tv.pkcs8),
error(that)
@ -178,24 +177,27 @@ TestArray.addTest(
"Import / export round-trip with 'spki'",
function() {
var that = this;
var alg = "RSAES-PKCS1-v1_5";
var alg = {
name: "RSASSA-PKCS1-v1_5",
hash: "SHA-256"
};
function doExport(x) {
if (!hasKeyFields(x)) {
throw "Invalid key; missing field(s)";
} else if ((x.algorithm.name != alg) ||
} else if ((x.algorithm.name != alg.name) ||
(x.algorithm.modulusLength != 1024) ||
(x.algorithm.publicExponent.byteLength != 3) ||
(x.type != "public") ||
(!x.extractable) ||
(x.usages.length != 1) ||
(x.usages[0] != 'encrypt')){
(x.usages[0] != 'verify')){
throw "Invalid key: incorrect key data";
}
return crypto.subtle.exportKey("spki", x);
}
crypto.subtle.importKey("spki", tv.spki, alg, true, ["encrypt"])
crypto.subtle.importKey("spki", tv.spki, alg, true, ["verify"])
.then(doExport, error(that))
.then(
memcmp_complete(that, tv.spki),
@ -209,7 +211,10 @@ TestArray.addTest(
"Import failure with format 'spki'",
function() {
var that = this;
var alg = "RSAES-PKCS1-v1_5";
var alg = {
name: "RSASSA-PKCS1-v1_5",
hash: "SHA-256"
};
crypto.subtle.importKey("spki", tv.negative_spki, alg, true, ["encrypt"])
.then(error(that), complete(that));
@ -382,11 +387,12 @@ TestArray.addTest(
function() {
var that = this;
var alg = {
name: "RSAES-PKCS1-v1_5",
name: "RSASSA-PKCS1-v1_5",
hash: "SHA-256",
modulusLength: 1024,
publicExponent: new Uint8Array([0x01, 0x00, 0x01])
};
crypto.subtle.generateKey(alg, false, ["encrypt", "decrypt"]).then(
crypto.subtle.generateKey(alg, false, ["sign", "verify"]).then(
complete(that, function(x) {
return exists(x.publicKey) &&
(x.publicKey.algorithm.name == alg.name) &&
@ -394,14 +400,14 @@ TestArray.addTest(
(x.publicKey.type == "public") &&
x.publicKey.extractable &&
(x.publicKey.usages.length == 1) &&
(x.publicKey.usages[0] == "encrypt") &&
(x.publicKey.usages[0] == "verify") &&
exists(x.privateKey) &&
(x.privateKey.algorithm.name == alg.name) &&
(x.privateKey.algorithm.modulusLength == alg.modulusLength) &&
(x.privateKey.type == "private") &&
!x.privateKey.extractable &&
(x.privateKey.usages.length == 1) &&
(x.privateKey.usages[0] == "decrypt");
(x.privateKey.usages[0] == "sign");
}),
error(that)
);
@ -414,12 +420,13 @@ TestArray.addTest(
function() {
var that = this;
var alg = {
name: "RSAES-PKCS1-v1_5",
name: "RSASSA-PKCS1-v1_5",
hash: "SHA-256",
modulusLength: 2299, // NSS does not like this key length
publicExponent: new Uint8Array([0x01, 0x00, 0x01])
};
crypto.subtle.generateKey(alg, false, ["encrypt"])
crypto.subtle.generateKey(alg, false, ["sign"])
.then( error(that), complete(that) );
}
);
@ -455,7 +462,6 @@ TestArray.addTest(
var that = this;
function doEncrypt(x) {
console.log(x);
return crypto.subtle.encrypt(
{ name: "AES-CBC", iv: tv.aes_cbc_enc.iv },
x, tv.aes_cbc_enc.data);
@ -477,7 +483,6 @@ TestArray.addTest(
var that = this;
function encrypt(x, iv) {
console.log(x);
return crypto.subtle.encrypt(
{ name: "AES-CBC", iv: iv },
x, tv.aes_cbc_enc.data);
@ -822,58 +827,6 @@ TestArray.addTest(
}
);
// -----------------------------------------------------------------------------
TestArray.addTest(
"RSAES-PKCS#1 encrypt/decrypt round-trip",
function () {
var that = this;
var privKey, pubKey;
var alg = {name:"RSAES-PKCS1-v1_5"};
var privKey, pubKey, data, ct, pt;
function setPriv(x) { privKey = x; }
function setPub(x) { pubKey = x; }
function doEncrypt() {
return crypto.subtle.encrypt(alg.name, pubKey, tv.rsaes.data);
}
function doDecrypt(x) {
return crypto.subtle.decrypt(alg.name, privKey, x);
}
function fail() { error(that); }
Promise.all([
crypto.subtle.importKey("pkcs8", tv.rsaes.pkcs8, alg, false, ['decrypt'])
.then(setPriv, error(that)),
crypto.subtle.importKey("spki", tv.rsaes.spki, alg, false, ['encrypt'])
.then(setPub, error(that))
]).then(doEncrypt, error(that))
.then(doDecrypt, error(that))
.then(
memcmp_complete(that, tv.rsaes.data),
error(that)
);
}
);
// -----------------------------------------------------------------------------
TestArray.addTest(
"RSAES-PKCS#1 decryption known answer",
function () {
var that = this;
var alg = {name:"RSAES-PKCS1-v1_5"};
function doDecrypt(x) {
return crypto.subtle.decrypt(alg.name, x, tv.rsaes.result);
}
function fail() { error(that); }
crypto.subtle.importKey("pkcs8", tv.rsaes.pkcs8, alg, false, ['decrypt'])
.then( doDecrypt, fail )
.then( memcmp_complete(that, tv.rsaes.data), fail );
}
);
// -----------------------------------------------------------------------------
TestArray.addTest(
"RSASSA/SHA-1 signature",
@ -882,15 +835,12 @@ TestArray.addTest(
var alg = { name: "RSASSA-PKCS1-v1_5", hash: "SHA-1" };
function doSign(x) {
console.log("sign");
console.log(x);
return crypto.subtle.sign(alg.name, x, tv.rsassa.data);
}
function fail() { console.log("fail"); error(that); }
crypto.subtle.importKey("pkcs8", tv.rsassa.pkcs8, alg, false, ['sign'])
.then( doSign, fail )
.then( memcmp_complete(that, tv.rsassa.sig1), fail );
.then( doSign )
.then( memcmp_complete(that, tv.rsassa.sig1), error(that) );
}
);
@ -904,13 +854,12 @@ TestArray.addTest(
function doVerify(x) {
return crypto.subtle.verify(alg.name, x, tv.rsassa.sig1, tv.rsassa.data);
}
function fail(x) { error(that); }
crypto.subtle.importKey("spki", tv.rsassa.spki, alg, false, ['verify'])
.then( doVerify, fail )
.then( doVerify )
.then(
complete(that, function(x) { return x; }),
fail
error(that)
);
}
);
@ -925,13 +874,12 @@ TestArray.addTest(
function doVerify(x) {
return crypto.subtle.verify(alg.name, x, tv.rsassa.sig_fail, tv.rsassa.data);
}
function fail(x) { error(that); }
crypto.subtle.importKey("spki", tv.rsassa.spki, alg, false, ['verify'])
.then( doVerify, fail )
.then( doVerify )
.then(
complete(that, function(x) { return !x; }),
fail
error(that)
);
}
);
@ -946,11 +894,10 @@ TestArray.addTest(
function doSign(x) {
return crypto.subtle.sign(alg.name, x, tv.rsassa.data);
}
function fail(x) { console.log(x); error(that); }
crypto.subtle.importKey("pkcs8", tv.rsassa.pkcs8, alg, false, ['sign'])
.then( doSign, fail )
.then( memcmp_complete(that, tv.rsassa.sig256), fail );
.then( doSign )
.then( memcmp_complete(that, tv.rsassa.sig256), error(that) );
}
);
@ -964,13 +911,12 @@ TestArray.addTest(
function doVerify(x) {
return crypto.subtle.verify(alg.name, x, tv.rsassa.sig256, tv.rsassa.data);
}
function fail(x) { error(that); }
crypto.subtle.importKey("spki", tv.rsassa.spki, alg, false, ['verify'])
.then( doVerify, fail )
.then( doVerify )
.then(
complete(that, function(x) { return x; }),
fail
error(that)
);
}
);
@ -984,17 +930,14 @@ TestArray.addTest(
var use = ['sign', 'verify'];
function doVerify(x) {
console.log("verifying")
return crypto.subtle.verify(alg.name, x, tv.rsassa.sig_fail, tv.rsassa.data);
}
function fail(x) { console.log("failing"); error(that)(x); }
console.log("running")
crypto.subtle.importKey("spki", tv.rsassa.spki, alg, false, ['verify'])
.then( doVerify, fail )
.then( doVerify )
.then(
complete(that, function(x) { return !x; }),
fail
error(that)
);
}
);
@ -1175,20 +1118,18 @@ TestArray.addTest(
true, ['sign', 'verify']);
}
function temperr(x) { return function(y) { console.log("error in "+x); console.log(y); } }
Promise.all([
crypto.subtle.importKey("jwk", tv.aes_gcm_enc.key_jwk,
"AES-GCM", false, ['wrapKey','unwrapKey'])
.then(function(x) { console.log("wrapKey"); wrapKey = x; }),
.then(function(x) { wrapKey = x; }),
crypto.subtle.generateKey(genAlg, true, ['sign', 'verify'])
.then(function(x) { console.log("originalKey"); originalKey = x; return x; })
.then(function(x) { originalKey = x; return x; })
.then(doExport)
.then(function(x) { originalKeyJwk = x; })
])
.then(doWrap, temperr("initial phase"))
.then(doUnwrap, temperr("wrap"))
.then(doExport, temperr("unwrap"))
.then(doWrap)
.then(doUnwrap)
.then(doExport)
.then(
complete(that, function(x) {
return exists(x.k) && x.k == originalKeyJwk.k;
@ -1269,9 +1210,9 @@ TestArray.addTest(
Promise.all([
crypto.subtle.importKey("jwk", tv.aes_kw.wrapping_key,
"AES-KW", false, ['wrapKey','unwrapKey'])
.then(function(x) { console.log("wrapKey"); wrapKey = x; }),
.then(function(x) { wrapKey = x; }),
crypto.subtle.generateKey(genAlg, true, ['sign'])
.then(function(x) { console.log("originalKey"); originalKey = x; return x; })
.then(function(x) { originalKey = x; return x; })
.then(doExport)
.then(function(x) { originalKeyJwk = x; })
])
@ -1332,7 +1273,7 @@ TestArray.addTest(
modulusLength: 2048,
publicExponent: new Uint8Array([0x01, 0x00, 0x01])
};
return crypto.subtle.generateKey(alg, false, ["encrypt"]);
return crypto.subtle.generateKey(alg, false, ["encrypt", "decrypt"]);
}
function doGenerateRsaSsaPkcs1Key() {
@ -1364,24 +1305,7 @@ TestArray.addTest(
return crypto.subtle.generateKey(alg, false, ["sign"]).then(doSign);
}
function doCheckRSAES() {
var alg = {
name: "RSAES-PKCS1-v1_5",
modulusLength: 1024,
publicExponent: new Uint8Array([0x01, 0x00, 0x01])
};
function doEncrypt(x) {
var alg = {name: "RSA-OAEP", hash: "SHA-1"};
return crypto.subtle.encrypt(alg, x.publicKey, new Uint8Array());
}
return crypto.subtle.generateKey(alg, false, ["encrypt"]).then(doEncrypt);
}
doCheckRSASSA().then(error(that), function () {
doCheckRSAES().then(error(that), complete(that));
});
doCheckRSASSA().then(error(that), complete(that));
}
);
/*]]>*/</script>

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

@ -103,7 +103,7 @@ TestArray.addTest(
modulusLength: 2048,
publicExponent: new Uint8Array([0x01, 0x00, 0x01])
};
return crypto.subtle.generateKey(alg, false, ["encrypt"])
return crypto.subtle.generateKey(alg, false, ["encrypt", "decrypt"])
}
function doDerive() {
@ -336,12 +336,12 @@ TestArray.addTest(
}
Promise.all([
crypto.subtle.importKey("jwk", tv.ecdh_p521.jwk_priv, alg, false, ["deriveBits"])
.then(setPriv, error(that)),
crypto.subtle.importKey("jwk", tv.ecdh_p521.jwk_pub, alg, false, ["deriveBits"])
.then(setPub, error(that))
]).then(doDerive, error(that))
.then(doSignAndVerify, error(that))
crypto.subtle.importKey("jwk", tv.ecdh_p521.jwk_priv, alg, false, ["deriveKey"])
.then(setPriv),
crypto.subtle.importKey("jwk", tv.ecdh_p521.jwk_pub, alg, false, ["deriveKey"])
.then(setPub)
]).then(doDerive)
.then(doSignAndVerify)
.then(complete(that), error(that));
}
);

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

@ -192,8 +192,6 @@ TestArray.addTest(
.then(doExport)
.then(
complete(that, function(x) {
window.jwk_priv = x;
console.log(JSON.stringify(x));
return hasBaseJwkFields(x) &&
hasFields(x, ['n', 'e', 'd', 'p', 'q', 'dp', 'dq', 'qi']) &&
x.kty == 'RSA' &&

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

@ -46,7 +46,6 @@ TestArray.addTest(
var key = tv.pbkdf2_sha1.password;
function doDerive(x) {
console.log("deriving");
if (!hasKeyFields(x)) {
throw "Invalid key; missing field(s)";
}
@ -61,7 +60,7 @@ TestArray.addTest(
}
function fail(x) { console.log("failing"); error(that)(x); }
crypto.subtle.importKey("raw", key, alg, false, ["deriveKey"])
crypto.subtle.importKey("raw", key, alg, false, ["deriveBits"])
.then( doDerive, fail )
.then( memcmp_complete(that, tv.pbkdf2_sha1.derived), fail );
}
@ -76,7 +75,6 @@ TestArray.addTest(
var key = tv.pbkdf2_sha1.password;
function doDerive(x) {
console.log("deriving");
if (!hasKeyFields(x)) {
throw "Invalid key; missing field(s)";
}
@ -161,7 +159,6 @@ TestArray.addTest(
var key = tv.pbkdf2_sha256.password;
function doDerive(x) {
console.log("deriving");
if (!hasKeyFields(x)) {
throw "Invalid key; missing field(s)";
}

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

@ -120,12 +120,13 @@ TestArray.addTest(
var privKey, pubKey;
function setKey(x) { pubKey = x.publicKey; privKey = x.privateKey; }
function doEncrypt(n) {
console.log("entered encrypt("+ n +")");
return function () {
return crypto.subtle.encrypt(alg, pubKey, new Uint8Array(n));
}
}
crypto.subtle.generateKey(alg, false, ['encrypt'])
crypto.subtle.generateKey(alg, false, ['encrypt', 'decrypt'])
.then(setKey, error(that))
.then(doEncrypt(214), error(that))
.then(doEncrypt(215), error(that))

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

@ -244,8 +244,6 @@ var interfaceNamesInGlobalScope =
"Crypto",
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "CryptoKey", pref: "dom.webcrypto.enabled"},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "CryptoKeyPair", pref: "dom.webcrypto.enabled"},
// IMPORTANT: Do not change this list without review from a DOM peer!
"CSS",
// IMPORTANT: Do not change this list without review from a DOM peer!

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

@ -0,0 +1,32 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* The origin of this IDL file is
* http://www.w3.org/TR/WebCryptoAPI/
*/
dictionary KeyAlgorithm {
required DOMString name;
};
dictionary AesKeyAlgorithm : KeyAlgorithm {
required unsigned short length;
};
dictionary EcKeyAlgorithm : KeyAlgorithm {
required DOMString namedCurve;
};
dictionary HmacKeyAlgorithm : KeyAlgorithm {
required KeyAlgorithm hash;
required unsigned long length;
};
dictionary RsaHashedKeyAlgorithm : KeyAlgorithm {
required unsigned short modulusLength;
required Uint8Array publicExponent;
required KeyAlgorithm hash;
};

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

@ -9,113 +9,74 @@
typedef DOMString KeyType;
typedef DOMString KeyUsage;
typedef DOMString NamedCurve;
typedef Uint8Array BigInteger;
/***** KeyAlgorithm interfaces *****/
[NoInterfaceObject]
interface KeyAlgorithm {
readonly attribute DOMString name;
};
[NoInterfaceObject]
interface AesKeyAlgorithm : KeyAlgorithm {
readonly attribute unsigned short length;
};
[NoInterfaceObject]
interface HmacKeyAlgorithm : KeyAlgorithm {
readonly attribute KeyAlgorithm hash;
readonly attribute unsigned long length;
};
[NoInterfaceObject]
interface RsaKeyAlgorithm : KeyAlgorithm {
readonly attribute unsigned long modulusLength;
[Throws]
readonly attribute BigInteger publicExponent;
};
[NoInterfaceObject]
interface RsaHashedKeyAlgorithm : RsaKeyAlgorithm {
readonly attribute KeyAlgorithm hash;
};
[NoInterfaceObject]
interface EcKeyAlgorithm : KeyAlgorithm {
readonly attribute NamedCurve namedCurve;
};
/***** Algorithm dictionaries *****/
dictionary Algorithm {
DOMString name;
required DOMString name;
};
dictionary AesCbcParams : Algorithm {
CryptoOperationData iv;
required CryptoOperationData iv;
};
dictionary AesCtrParams : Algorithm {
CryptoOperationData counter;
[EnforceRange] octet length;
required CryptoOperationData counter;
[EnforceRange] required octet length;
};
dictionary AesGcmParams : Algorithm {
CryptoOperationData iv;
required CryptoOperationData iv;
CryptoOperationData additionalData;
[EnforceRange] octet tagLength;
};
dictionary HmacImportParams : Algorithm {
AlgorithmIdentifier hash;
required AlgorithmIdentifier hash;
};
dictionary Pbkdf2Params : Algorithm {
CryptoOperationData salt;
[EnforceRange] unsigned long iterations;
AlgorithmIdentifier hash;
required CryptoOperationData salt;
[EnforceRange] required unsigned long iterations;
required AlgorithmIdentifier hash;
};
dictionary RsaHashedImportParams {
AlgorithmIdentifier hash;
required AlgorithmIdentifier hash;
};
dictionary AesKeyGenParams : Algorithm {
[EnforceRange] unsigned short length;
[EnforceRange] required unsigned short length;
};
dictionary HmacKeyGenParams : Algorithm {
AlgorithmIdentifier hash;
required AlgorithmIdentifier hash;
[EnforceRange] unsigned long length;
};
dictionary RsaKeyGenParams : Algorithm {
[EnforceRange] unsigned long modulusLength;
BigInteger publicExponent;
};
dictionary RsaHashedKeyGenParams : RsaKeyGenParams {
AlgorithmIdentifier hash;
dictionary RsaHashedKeyGenParams : Algorithm {
[EnforceRange] required unsigned long modulusLength;
required BigInteger publicExponent;
required AlgorithmIdentifier hash;
};
dictionary RsaOaepParams : Algorithm {
CryptoOperationData? label;
CryptoOperationData label;
};
dictionary DhKeyGenParams : Algorithm {
BigInteger prime;
BigInteger generator;
required BigInteger prime;
required BigInteger generator;
};
typedef DOMString NamedCurve;
dictionary EcKeyGenParams : Algorithm {
NamedCurve namedCurve;
required NamedCurve namedCurve;
};
dictionary AesDerivedKeyParams : Algorithm {
[EnforceRange] unsigned long length;
[EnforceRange] required unsigned long length;
};
dictionary HmacDerivedKeyParams : HmacImportParams {
@ -123,7 +84,7 @@ dictionary HmacDerivedKeyParams : HmacImportParams {
};
dictionary EcdhKeyDeriveParams : Algorithm {
CryptoKey public;
required CryptoKey public;
};
@ -131,14 +92,14 @@ dictionary EcdhKeyDeriveParams : Algorithm {
dictionary RsaOtherPrimesInfo {
// The following fields are defined in Section 6.3.2.7 of JSON Web Algorithms
DOMString r;
DOMString d;
DOMString t;
required DOMString r;
required DOMString d;
required DOMString t;
};
dictionary JsonWebKey {
// The following fields are defined in Section 3.1 of JSON Web Key
DOMString kty;
required DOMString kty;
DOMString use;
sequence<DOMString> key_ops;
DOMString alg;
@ -169,14 +130,13 @@ dictionary JsonWebKey {
interface CryptoKey {
readonly attribute KeyType type;
readonly attribute boolean extractable;
readonly attribute KeyAlgorithm algorithm;
[Cached, Constant, Throws] readonly attribute object algorithm;
[Cached, Constant, Frozen] readonly attribute sequence<KeyUsage> usages;
};
[Pref="dom.webcrypto.enabled"]
interface CryptoKeyPair {
readonly attribute CryptoKey publicKey;
readonly attribute CryptoKey privateKey;
dictionary CryptoKeyPair {
required CryptoKey publicKey;
required CryptoKey privateKey;
};
typedef DOMString KeyFormat;

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

@ -238,6 +238,7 @@ WEBIDL_FILES = [
'InterAppConnection.webidl',
'InterAppConnectionRequest.webidl',
'InterAppMessagePort.webidl',
'KeyAlgorithm.webidl',
'KeyboardEvent.webidl',
'KeyEvent.webidl',
'LegacyQueryInterface.webidl',