2015-05-03 19:32:37 +00:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
2014-05-15 10:20:00 +00:00
|
|
|
/* 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/. */
|
|
|
|
|
2014-06-23 21:25:13 +00:00
|
|
|
#ifndef mozilla_dom_CryptoKey_h
|
|
|
|
#define mozilla_dom_CryptoKey_h
|
2014-05-15 10:20:00 +00:00
|
|
|
|
|
|
|
#include "nsCycleCollectionParticipant.h"
|
|
|
|
#include "nsWrapperCache.h"
|
|
|
|
#include "nsIGlobalObject.h"
|
|
|
|
#include "nsNSSShutDown.h"
|
|
|
|
#include "pk11pub.h"
|
|
|
|
#include "keyhi.h"
|
|
|
|
#include "ScopedNSSTypes.h"
|
2014-09-27 18:22:57 +00:00
|
|
|
#include "mozilla/ErrorResult.h"
|
2014-05-15 10:20:00 +00:00
|
|
|
#include "mozilla/dom/CryptoBuffer.h"
|
2014-09-27 18:22:57 +00:00
|
|
|
#include "mozilla/dom/KeyAlgorithmProxy.h"
|
2014-05-15 10:20:00 +00:00
|
|
|
#include "js/StructuredClone.h"
|
|
|
|
#include "js/TypeDecls.h"
|
|
|
|
|
2014-09-27 18:22:57 +00:00
|
|
|
#define CRYPTOKEY_SC_VERSION 0x00000001
|
|
|
|
|
2014-05-15 10:20:00 +00:00
|
|
|
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)
|
2014-06-23 21:25:13 +00:00
|
|
|
* The actual keys (which the CryptoKey must serialize)
|
2014-05-15 10:20:00 +00:00
|
|
|
|
|
|
|
*/
|
|
|
|
|
2014-07-19 13:25:00 +00:00
|
|
|
struct JsonWebKey;
|
|
|
|
|
2015-03-21 16:28:04 +00:00
|
|
|
class CryptoKey final : public nsISupports,
|
2015-03-27 18:52:19 +00:00
|
|
|
public nsWrapperCache,
|
|
|
|
public nsNSSShutDownObject
|
2014-05-15 10:20:00 +00:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
2014-06-23 21:25:13 +00:00
|
|
|
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(CryptoKey)
|
2014-05-15 10:20:00 +00:00
|
|
|
|
|
|
|
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
|
|
|
|
};
|
|
|
|
|
2014-09-02 00:49:25 +00:00
|
|
|
explicit CryptoKey(nsIGlobalObject* aWindow);
|
2014-05-15 10:20:00 +00:00
|
|
|
|
|
|
|
nsIGlobalObject* GetParentObject() const
|
|
|
|
{
|
|
|
|
return mGlobal;
|
|
|
|
}
|
|
|
|
|
2015-03-21 16:28:04 +00:00
|
|
|
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
2014-05-15 10:20:00 +00:00
|
|
|
|
|
|
|
// WebIDL methods
|
|
|
|
void GetType(nsString& aRetVal) const;
|
|
|
|
bool Extractable() const;
|
2014-09-27 18:22:57 +00:00
|
|
|
void GetAlgorithm(JSContext* cx, JS::MutableHandle<JSObject*> aRetVal,
|
|
|
|
ErrorResult& aRv) const;
|
2014-05-15 10:20:00 +00:00
|
|
|
void GetUsages(nsTArray<nsString>& aRetVal) const;
|
|
|
|
|
|
|
|
// The below methods are not exposed to JS, but C++ can use
|
|
|
|
// them to manipulate the object
|
|
|
|
|
2014-09-27 18:22:57 +00:00
|
|
|
KeyAlgorithmProxy& Algorithm();
|
|
|
|
const KeyAlgorithmProxy& Algorithm() const;
|
2014-05-15 10:20:00 +00:00
|
|
|
KeyType GetKeyType() const;
|
|
|
|
nsresult SetType(const nsString& aType);
|
|
|
|
void SetType(KeyType aType);
|
|
|
|
void SetExtractable(bool aExtractable);
|
2015-04-25 12:53:43 +00:00
|
|
|
nsresult AddPublicKeyData(SECKEYPublicKey* point);
|
2014-05-15 10:20:00 +00:00
|
|
|
void ClearUsages();
|
|
|
|
nsresult AddUsage(const nsString& aUsage);
|
2014-05-26 10:05:00 +00:00
|
|
|
nsresult AddUsageIntersecting(const nsString& aUsage, uint32_t aUsageMask);
|
2014-05-15 10:20:00 +00:00
|
|
|
void AddUsage(KeyUsage aUsage);
|
2014-09-27 18:22:57 +00:00
|
|
|
bool HasAnyUsage();
|
2014-05-15 10:20:00 +00:00
|
|
|
bool HasUsage(KeyUsage aUsage);
|
|
|
|
bool HasUsageOtherThan(uint32_t aUsages);
|
2014-09-27 18:22:57 +00:00
|
|
|
static bool IsRecognizedUsage(const nsString& aUsage);
|
|
|
|
static bool AllUsagesRecognized(const Sequence<nsString>& aUsages);
|
2014-05-15 10:20:00 +00:00
|
|
|
|
2015-09-14 09:19:16 +00:00
|
|
|
nsresult SetSymKey(const CryptoBuffer& aSymKey);
|
2015-09-14 09:53:02 +00:00
|
|
|
nsresult SetPrivateKey(SECKEYPrivateKey* aPrivateKey);
|
|
|
|
nsresult SetPublicKey(SECKEYPublicKey* aPublicKey);
|
2014-05-15 10:20:00 +00:00
|
|
|
|
|
|
|
// 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
|
2015-03-21 16:28:04 +00:00
|
|
|
virtual void virtualDestroyNSSReference() override;
|
2014-05-15 10:20:00 +00:00
|
|
|
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*/);
|
2015-04-27 16:48:36 +00:00
|
|
|
static nsresult PublicKeyToSpki(SECKEYPublicKey* aPubKey,
|
2014-05-15 10:20:00 +00:00
|
|
|
CryptoBuffer& aRetVal,
|
|
|
|
const nsNSSShutDownPreventionLock& /*proofOfLock*/);
|
|
|
|
|
2014-07-19 13:25:00 +00:00
|
|
|
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*/);
|
2015-04-27 16:48:36 +00:00
|
|
|
static nsresult PublicKeyToJwk(SECKEYPublicKey* aPubKey,
|
2014-07-19 13:25:00 +00:00
|
|
|
JsonWebKey& aRetVal,
|
|
|
|
const nsNSSShutDownPreventionLock& /*proofOfLock*/);
|
|
|
|
|
2014-08-22 10:02:14 +00:00
|
|
|
static SECKEYPublicKey* PublicDhKeyFromRaw(CryptoBuffer& aKeyData,
|
|
|
|
const CryptoBuffer& aPrime,
|
|
|
|
const CryptoBuffer& aGenerator,
|
|
|
|
const nsNSSShutDownPreventionLock& /*proofOfLock*/);
|
|
|
|
static nsresult PublicDhKeyToRaw(SECKEYPublicKey* aPubKey,
|
|
|
|
CryptoBuffer& aRetVal,
|
|
|
|
const nsNSSShutDownPreventionLock& /*proofOfLock*/);
|
|
|
|
|
2015-04-28 07:13:16 +00:00
|
|
|
static SECKEYPublicKey* PublicECKeyFromRaw(CryptoBuffer& aKeyData,
|
|
|
|
const nsString& aNamedCurve,
|
|
|
|
const nsNSSShutDownPreventionLock& /*proofOfLock*/);
|
|
|
|
static nsresult PublicECKeyToRaw(SECKEYPublicKey* aPubKey,
|
|
|
|
CryptoBuffer& aRetVal,
|
|
|
|
const nsNSSShutDownPreventionLock& /*proofOfLock*/);
|
|
|
|
|
2014-10-13 21:19:00 +00:00
|
|
|
static bool PublicKeyValid(SECKEYPublicKey* aPubKey);
|
|
|
|
|
2014-05-15 10:20:00 +00:00
|
|
|
// Structured clone methods use these to clone keys
|
|
|
|
bool WriteStructuredClone(JSStructuredCloneWriter* aWriter) const;
|
|
|
|
bool ReadStructuredClone(JSStructuredCloneReader* aReader);
|
|
|
|
|
|
|
|
private:
|
2014-06-23 21:25:13 +00:00
|
|
|
~CryptoKey();
|
2014-06-23 19:56:07 +00:00
|
|
|
|
2015-10-18 05:24:48 +00:00
|
|
|
RefPtr<nsIGlobalObject> mGlobal;
|
2014-05-15 10:20:00 +00:00
|
|
|
uint32_t mAttributes; // see above
|
2014-09-27 18:22:57 +00:00
|
|
|
KeyAlgorithmProxy mAlgorithm;
|
2014-05-15 10:20:00 +00:00
|
|
|
|
|
|
|
// Only one key handle should be set, according to the KeyType
|
|
|
|
CryptoBuffer mSymKey;
|
|
|
|
ScopedSECKEYPrivateKey mPrivateKey;
|
|
|
|
ScopedSECKEYPublicKey mPublicKey;
|
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace dom
|
|
|
|
} // namespace mozilla
|
|
|
|
|
2014-06-23 21:25:13 +00:00
|
|
|
#endif // mozilla_dom_CryptoKey_h
|