tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

CryptoKey.h (7042B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef mozilla_dom_CryptoKey_h
      8 #define mozilla_dom_CryptoKey_h
      9 
     10 #include <cstdint>
     11 
     12 #include "ErrorList.h"
     13 #include "ScopedNSSTypes.h"
     14 #include "js/RootingAPI.h"
     15 #include "keythi.h"
     16 #include "mozilla/AlreadyAddRefed.h"
     17 #include "mozilla/RefPtr.h"
     18 #include "mozilla/dom/BindingDeclarations.h"
     19 #include "mozilla/dom/CryptoBuffer.h"
     20 #include "mozilla/dom/KeyAlgorithmProxy.h"
     21 #include "nsCycleCollectionParticipant.h"
     22 #include "nsIGlobalObject.h"
     23 #include "nsISupports.h"
     24 #include "nsStringFwd.h"
     25 #include "nsTArrayForwardDeclare.h"
     26 #include "nsWrapperCache.h"
     27 
     28 #define CRYPTOKEY_SC_VERSION 0x00000001
     29 
     30 class JSObject;
     31 class nsIGlobalObject;
     32 struct JSContext;
     33 struct JSStructuredCloneReader;
     34 struct JSStructuredCloneWriter;
     35 
     36 namespace mozilla {
     37 
     38 class ErrorResult;
     39 
     40 namespace dom {
     41 
     42 /*
     43 
     44 The internal structure of keys is dictated by the need for cloning.
     45 We store everything besides the key data itself in a 32-bit bitmask,
     46 with the following structure (byte-aligned for simplicity, in order
     47 from least to most significant):
     48 
     49 Bits  Usage
     50 0     Extractable
     51 1-7   [reserved]
     52 8-15  KeyType
     53 16-23 KeyUsage
     54 24-31 [reserved]
     55 
     56 In the order of a hex value for a uint32_t
     57 
     58   3                   2                   1                   0
     59 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
     60 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     61 |~~~~~~~~~~~~~~~|     Usage     |     Type      |~~~~~~~~~~~~~|E|
     62 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     63 
     64 Thus, internally, a key has the following fields:
     65 * uint32_t - flags for extractable, usage, type
     66 * KeyAlgorithm - the algorithm (which must serialize/deserialize itself)
     67 * The actual keys (which the CryptoKey must serialize)
     68 
     69 */
     70 
     71 struct JsonWebKey;
     72 
     73 class CryptoKey final : public nsISupports, public nsWrapperCache {
     74 public:
     75  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
     76  NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(CryptoKey)
     77 
     78  static const uint32_t CLEAR_EXTRACTABLE = 0xFFFFFFE;
     79  static const uint32_t EXTRACTABLE = 0x00000001;
     80 
     81  static const uint32_t CLEAR_TYPE = 0xFFFF00FF;
     82  static const uint32_t TYPE_MASK = 0x0000FF00;
     83  enum KeyType {
     84    UNKNOWN = 0x00000000,
     85    SECRET = 0x00000100,
     86    PUBLIC = 0x00000200,
     87    PRIVATE = 0x00000300
     88  };
     89 
     90  static const uint32_t CLEAR_USAGES = 0xFF00FFFF;
     91  static const uint32_t USAGES_MASK = 0x00FF0000;
     92  enum KeyUsage {
     93    ENCRYPT = 0x00010000,
     94    DECRYPT = 0x00020000,
     95    SIGN = 0x00040000,
     96    VERIFY = 0x00080000,
     97    DERIVEKEY = 0x00100000,
     98    DERIVEBITS = 0x00200000,
     99    WRAPKEY = 0x00400000,
    100    UNWRAPKEY = 0x00800000
    101  };
    102 
    103  explicit CryptoKey(nsIGlobalObject* aWindow);
    104 
    105  nsIGlobalObject* GetParentObject() const { return mGlobal; }
    106 
    107  virtual JSObject* WrapObject(JSContext* aCx,
    108                               JS::Handle<JSObject*> aGivenProto) override;
    109 
    110  // WebIDL methods
    111  void GetType(nsString& aRetVal) const;
    112  bool Extractable() const;
    113  void GetAlgorithm(JSContext* cx, JS::MutableHandle<JSObject*> aRetVal,
    114                    ErrorResult& aRv) const;
    115  void GetUsages(nsTArray<nsString>& aRetVal) const;
    116 
    117  // The below methods are not exposed to JS, but C++ can use
    118  // them to manipulate the object
    119 
    120  KeyAlgorithmProxy& Algorithm();
    121  const KeyAlgorithmProxy& Algorithm() const;
    122  KeyType GetKeyType() const;
    123  nsresult SetType(const nsString& aType);
    124  void SetType(KeyType aType);
    125  void SetExtractable(bool aExtractable);
    126  nsresult AddPublicKeyData(SECKEYPublicKey* aPublicKey);
    127  void ClearUsages();
    128  nsresult AddUsage(const nsString& aUsage);
    129  nsresult AddAllowedUsage(const nsString& aUsage, const nsString& aAlgorithm);
    130  nsresult AddAllowedUsageIntersecting(const nsString& aUsage,
    131                                       const nsString& aAlgorithm,
    132                                       uint32_t aUsageMask = USAGES_MASK);
    133  void AddUsage(KeyUsage aUsage);
    134  bool HasAnyUsage();
    135  bool HasUsage(KeyUsage aUsage);
    136  bool HasUsageOtherThan(uint32_t aUsages);
    137  static bool IsRecognizedUsage(const nsString& aUsage);
    138  static bool AllUsagesRecognized(const Sequence<nsString>& aUsages);
    139  static uint32_t GetAllowedUsagesForAlgorithm(const nsString& aAlgorithm);
    140 
    141  nsresult SetSymKey(const CryptoBuffer& aSymKey);
    142  nsresult SetPrivateKey(SECKEYPrivateKey* aPrivateKey);
    143  nsresult SetPublicKey(SECKEYPublicKey* aPublicKey);
    144 
    145  // Accessors for the keys themselves
    146  const CryptoBuffer& GetSymKey() const;
    147  UniqueSECKEYPrivateKey GetPrivateKey() const;
    148  UniqueSECKEYPublicKey GetPublicKey() const;
    149 
    150  // Serialization and deserialization convenience methods
    151  // Note:
    152  // 1. The inputs aKeyData are non-const only because the NSS import
    153  //    functions lack the const modifier.  They should not be modified.
    154  // 2. All of the NSS key objects returned need to be freed by the caller.
    155  static UniqueSECKEYPrivateKey PrivateKeyFromPkcs8(CryptoBuffer& aKeyData);
    156  static nsresult PrivateKeyToPkcs8(SECKEYPrivateKey* aPrivKey,
    157                                    CryptoBuffer& aRetVal);
    158 
    159  static UniqueSECKEYPublicKey PublicKeyFromSpki(CryptoBuffer& aKeyData);
    160  static nsresult PublicKeyToSpki(SECKEYPublicKey* aPubKey,
    161                                  CryptoBuffer& aRetVal);
    162 
    163  static UniqueSECKEYPrivateKey PrivateKeyFromJwk(const JsonWebKey& aJwk);
    164  static nsresult PrivateKeyToJwk(SECKEYPrivateKey* aPrivKey,
    165                                  JsonWebKey& aRetVal);
    166 
    167  static UniqueSECKEYPublicKey PublicKeyFromJwk(const JsonWebKey& aKeyData);
    168  static nsresult PublicKeyToJwk(SECKEYPublicKey* aPubKey, JsonWebKey& aRetVal);
    169 
    170  static UniqueSECKEYPublicKey PublicECKeyFromRaw(CryptoBuffer& aKeyData,
    171                                                  const nsString& aNamedCurve);
    172  static nsresult PublicECKeyToRaw(SECKEYPublicKey* aPubKey,
    173                                   CryptoBuffer& aRetVal);
    174 
    175  static UniqueSECKEYPublicKey PublicOKPKeyFromRaw(CryptoBuffer& aKeyData,
    176                                                   const nsString& aNamedCurve);
    177 
    178  static bool PublicKeyValid(SECKEYPublicKey* aPubKey);
    179 
    180  // Structured clone methods use these to clone keys
    181  bool WriteStructuredClone(JSContext* aCx,
    182                            JSStructuredCloneWriter* aWriter) const;
    183  static already_AddRefed<CryptoKey> ReadStructuredClone(
    184      JSContext* aCx, nsIGlobalObject* aGlobal,
    185      JSStructuredCloneReader* aReader);
    186 
    187 private:
    188  ~CryptoKey() = default;
    189 
    190  RefPtr<nsIGlobalObject> mGlobal;
    191  uint32_t mAttributes;  // see above
    192  KeyAlgorithmProxy mAlgorithm;
    193 
    194  // Only one key handle should be set, according to the KeyType
    195  CryptoBuffer mSymKey;
    196  UniqueSECKEYPrivateKey mPrivateKey;
    197  UniqueSECKEYPublicKey mPublicKey;
    198 };
    199 
    200 }  // namespace dom
    201 }  // namespace mozilla
    202 
    203 #endif  // mozilla_dom_CryptoKey_h