diff options
author | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
---|---|---|
committer | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
commit | 5f8de423f190bbb79a62f804151bc24824fa32d8 (patch) | |
tree | 10027f336435511475e392454359edea8e25895d /dom/crypto/CryptoKey.h | |
parent | 49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff) | |
download | uxp-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz |
Add m-esr52 at 52.6.0
Diffstat (limited to 'dom/crypto/CryptoKey.h')
-rw-r--r-- | dom/crypto/CryptoKey.h | 212 |
1 files changed, 212 insertions, 0 deletions
diff --git a/dom/crypto/CryptoKey.h b/dom/crypto/CryptoKey.h new file mode 100644 index 0000000000..31f7a84aab --- /dev/null +++ b/dom/crypto/CryptoKey.h @@ -0,0 +1,212 @@ +/* -*- 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 "nsNSSShutDown.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 nsNSSShutDownObject +{ +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 + // Note: GetPrivateKey and GetPublicKey return copies of the internal + // key handles, which the caller must free with SECKEY_DestroyPrivateKey + // or SECKEY_DestroyPublicKey. + const CryptoBuffer& GetSymKey() const; + SECKEYPrivateKey* GetPrivateKey() const; + SECKEYPublicKey* GetPublicKey() const; + + // For nsNSSShutDownObject + virtual void virtualDestroyNSSReference() override; + void destructorSafeDestroyNSSReference(); + + // 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 SECKEYPrivateKey* PrivateKeyFromPkcs8(CryptoBuffer& aKeyData, + const nsNSSShutDownPreventionLock& /*proofOfLock*/); + static nsresult PrivateKeyToPkcs8(SECKEYPrivateKey* aPrivKey, + CryptoBuffer& aRetVal, + const nsNSSShutDownPreventionLock& /*proofOfLock*/); + + static SECKEYPublicKey* PublicKeyFromSpki(CryptoBuffer& aKeyData, + const nsNSSShutDownPreventionLock& /*proofOfLock*/); + static nsresult PublicKeyToSpki(SECKEYPublicKey* aPubKey, + CryptoBuffer& aRetVal, + const nsNSSShutDownPreventionLock& /*proofOfLock*/); + + static SECKEYPrivateKey* PrivateKeyFromJwk(const JsonWebKey& aJwk, + const nsNSSShutDownPreventionLock& /*proofOfLock*/); + static nsresult PrivateKeyToJwk(SECKEYPrivateKey* aPrivKey, + JsonWebKey& aRetVal, + const nsNSSShutDownPreventionLock& /*proofOfLock*/); + + static SECKEYPublicKey* PublicKeyFromJwk(const JsonWebKey& aKeyData, + const nsNSSShutDownPreventionLock& /*proofOfLock*/); + static nsresult PublicKeyToJwk(SECKEYPublicKey* aPubKey, + JsonWebKey& aRetVal, + const nsNSSShutDownPreventionLock& /*proofOfLock*/); + + static SECKEYPublicKey* PublicDhKeyFromRaw(CryptoBuffer& aKeyData, + const CryptoBuffer& aPrime, + const CryptoBuffer& aGenerator, + const nsNSSShutDownPreventionLock& /*proofOfLock*/); + static nsresult PublicDhKeyToRaw(SECKEYPublicKey* aPubKey, + CryptoBuffer& aRetVal, + const nsNSSShutDownPreventionLock& /*proofOfLock*/); + + static SECKEYPublicKey* PublicECKeyFromRaw(CryptoBuffer& aKeyData, + const nsString& aNamedCurve, + const nsNSSShutDownPreventionLock& /*proofOfLock*/); + static nsresult PublicECKeyToRaw(SECKEYPublicKey* aPubKey, + CryptoBuffer& aRetVal, + const nsNSSShutDownPreventionLock& /*proofOfLock*/); + + static bool PublicKeyValid(SECKEYPublicKey* aPubKey); + + // Structured clone methods use these to clone keys + bool WriteStructuredClone(JSStructuredCloneWriter* aWriter) const; + bool ReadStructuredClone(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; + ScopedSECKEYPrivateKey mPrivateKey; + ScopedSECKEYPublicKey mPublicKey; +}; + +} // namespace dom +} // namespace mozilla + +#endif // mozilla_dom_CryptoKey_h |