mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-22 09:45:41 +00:00
9c614370ec
Bug 1034856 added support for DH algorithms to WebCrypto, however the final specification did not choose to include them, making Firefox the only browser with support. Bug 1539578 added telemetry to show usage, and it is extremely low (not appearing on the graphs), which could be expected as Firefox is the only supporting browser. Since DH is an ongoing maintenance burden -- and overall cryptanalysis of DH is progressing -- let's remove it. Notice to unship went to dev-platform on 29 March 2019 with no objections. [0] [0] https://groups.google.com/d/msg/mozilla.dev.platform/Ut3-eQmUdWg/O9w1et1aBgAJ Differential Revision: https://phabricator.services.mozilla.com/D50865 --HG-- extra : moz-landing-system : lando
184 lines
6.2 KiB
C++
184 lines
6.2 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
/* 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_CryptoKey_h
|
|
#define mozilla_dom_CryptoKey_h
|
|
|
|
#include "nsCycleCollectionParticipant.h"
|
|
#include "nsWrapperCache.h"
|
|
#include "nsIGlobalObject.h"
|
|
#include "pk11pub.h"
|
|
#include "keyhi.h"
|
|
#include "ScopedNSSTypes.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 {
|
|
namespace dom {
|
|
|
|
/*
|
|
|
|
The internal structure of keys is dictated by the need for cloning.
|
|
We store everything besides the key data itself in a 32-bit bitmask,
|
|
with the following structure (byte-aligned for simplicity, in order
|
|
from least to most significant):
|
|
|
|
Bits Usage
|
|
0 Extractable
|
|
1-7 [reserved]
|
|
8-15 KeyType
|
|
16-23 KeyUsage
|
|
24-31 [reserved]
|
|
|
|
In the order of a hex value for a uint32_t
|
|
|
|
3 2 1 0
|
|
1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
|~~~~~~~~~~~~~~~| Usage | Type |~~~~~~~~~~~~~|E|
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
|
|
Thus, internally, a key has the following fields:
|
|
* uint32_t - flags for extractable, usage, type
|
|
* KeyAlgorithm - the algorithm (which must serialize/deserialize itself)
|
|
* The actual keys (which the CryptoKey must serialize)
|
|
|
|
*/
|
|
|
|
struct JsonWebKey;
|
|
|
|
class CryptoKey final : public nsISupports, public nsWrapperCache {
|
|
public:
|
|
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
|
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(CryptoKey)
|
|
|
|
static const uint32_t CLEAR_EXTRACTABLE = 0xFFFFFFE;
|
|
static const uint32_t EXTRACTABLE = 0x00000001;
|
|
|
|
static const uint32_t CLEAR_TYPE = 0xFFFF00FF;
|
|
static const uint32_t TYPE_MASK = 0x0000FF00;
|
|
enum KeyType {
|
|
UNKNOWN = 0x00000000,
|
|
SECRET = 0x00000100,
|
|
PUBLIC = 0x00000200,
|
|
PRIVATE = 0x00000300
|
|
};
|
|
|
|
static const uint32_t CLEAR_USAGES = 0xFF00FFFF;
|
|
static const uint32_t USAGES_MASK = 0x00FF0000;
|
|
enum KeyUsage {
|
|
ENCRYPT = 0x00010000,
|
|
DECRYPT = 0x00020000,
|
|
SIGN = 0x00040000,
|
|
VERIFY = 0x00080000,
|
|
DERIVEKEY = 0x00100000,
|
|
DERIVEBITS = 0x00200000,
|
|
WRAPKEY = 0x00400000,
|
|
UNWRAPKEY = 0x00800000
|
|
};
|
|
|
|
explicit CryptoKey(nsIGlobalObject* aWindow);
|
|
|
|
nsIGlobalObject* GetParentObject() const { return mGlobal; }
|
|
|
|
virtual JSObject* WrapObject(JSContext* aCx,
|
|
JS::Handle<JSObject*> aGivenProto) override;
|
|
|
|
// WebIDL methods
|
|
void GetType(nsString& aRetVal) const;
|
|
bool Extractable() 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);
|
|
nsresult AddPublicKeyData(SECKEYPublicKey* point);
|
|
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);
|
|
|
|
nsresult SetSymKey(const CryptoBuffer& aSymKey);
|
|
nsresult SetPrivateKey(SECKEYPrivateKey* aPrivateKey);
|
|
nsresult SetPublicKey(SECKEYPublicKey* aPublicKey);
|
|
|
|
// Accessors for the keys themselves
|
|
const CryptoBuffer& GetSymKey() const;
|
|
UniqueSECKEYPrivateKey GetPrivateKey() const;
|
|
UniqueSECKEYPublicKey GetPublicKey() const;
|
|
|
|
// Serialization and deserialization convenience methods
|
|
// Note:
|
|
// 1. The inputs aKeyData are non-const only because the NSS import
|
|
// functions lack the const modifier. They should not be modified.
|
|
// 2. All of the NSS key objects returned need to be freed by the caller.
|
|
static UniqueSECKEYPrivateKey PrivateKeyFromPkcs8(CryptoBuffer& aKeyData);
|
|
static nsresult PrivateKeyToPkcs8(SECKEYPrivateKey* aPrivKey,
|
|
CryptoBuffer& aRetVal);
|
|
|
|
static UniqueSECKEYPublicKey PublicKeyFromSpki(CryptoBuffer& aKeyData);
|
|
static nsresult PublicKeyToSpki(SECKEYPublicKey* aPubKey,
|
|
CryptoBuffer& aRetVal);
|
|
|
|
static UniqueSECKEYPrivateKey PrivateKeyFromJwk(const JsonWebKey& aJwk);
|
|
static nsresult PrivateKeyToJwk(SECKEYPrivateKey* aPrivKey,
|
|
JsonWebKey& aRetVal);
|
|
|
|
static UniqueSECKEYPublicKey PublicKeyFromJwk(const JsonWebKey& aKeyData);
|
|
static nsresult PublicKeyToJwk(SECKEYPublicKey* aPubKey, JsonWebKey& aRetVal);
|
|
|
|
static UniqueSECKEYPublicKey PublicECKeyFromRaw(CryptoBuffer& aKeyData,
|
|
const nsString& aNamedCurve);
|
|
static nsresult PublicECKeyToRaw(SECKEYPublicKey* aPubKey,
|
|
CryptoBuffer& aRetVal);
|
|
|
|
static bool PublicKeyValid(SECKEYPublicKey* aPubKey);
|
|
|
|
// Structured clone methods use these to clone keys
|
|
bool WriteStructuredClone(JSContext* aCx,
|
|
JSStructuredCloneWriter* aWriter) const;
|
|
static already_AddRefed<CryptoKey> ReadStructuredClone(
|
|
JSContext* aCx, nsIGlobalObject* aGlobal,
|
|
JSStructuredCloneReader* aReader);
|
|
|
|
private:
|
|
~CryptoKey() {}
|
|
|
|
RefPtr<nsIGlobalObject> mGlobal;
|
|
uint32_t mAttributes; // see above
|
|
KeyAlgorithmProxy mAlgorithm;
|
|
|
|
// Only one key handle should be set, according to the KeyType
|
|
CryptoBuffer mSymKey;
|
|
UniqueSECKEYPrivateKey mPrivateKey;
|
|
UniqueSECKEYPublicKey mPublicKey;
|
|
};
|
|
|
|
} // namespace dom
|
|
} // namespace mozilla
|
|
|
|
#endif // mozilla_dom_CryptoKey_h
|