summaryrefslogtreecommitdiffstats
path: root/dom/crypto/KeyAlgorithmProxy.h
blob: 30dd680f63a7e844aa033e8a50c3777c4194c130 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
/* -*- Mode: C++; tab-width: 8; 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/. */

#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;

  bool
  ToKeyAlgorithm(JSContext* aCx, RsaHashedKeyAlgorithm& aRsa) const
  {
    JS::Rooted<JSObject*> exponent(aCx, mPublicExponent.ToUint8Array(aCx));
    if (!exponent) {
      return false;
    }

    aRsa.mName = mName;
    aRsa.mModulusLength = mModulusLength;
    aRsa.mHash.mName = mHash.mName;
    aRsa.mPublicExponent.Init(exponent);
    aRsa.mPublicExponent.ComputeLengthAndData();

    return true;
  }
};

// A heap-safe variant of DhKeyAlgorithm
// The only difference is that it uses CryptoBuffers instead of Uint8Arrays
struct DhKeyAlgorithmStorage {
  nsString mName;
  CryptoBuffer mPrime;
  CryptoBuffer mGenerator;

  bool
  ToKeyAlgorithm(JSContext* aCx, DhKeyAlgorithm& aDh) const
  {
    JS::Rooted<JSObject*> prime(aCx, mPrime.ToUint8Array(aCx));
    if (!prime) {
      return false;
    }

    JS::Rooted<JSObject*> generator(aCx, mGenerator.ToUint8Array(aCx));
    if (!generator) {
      return false;
    }

    aDh.mName = mName;
    aDh.mPrime.Init(prime);
    aDh.mPrime.ComputeLengthAndData();
    aDh.mGenerator.Init(generator);
    aDh.mGenerator.ComputeLengthAndData();

    return true;
  }
};

// This class encapuslates a KeyAlgorithm object, and adds several
// methods that make WebCrypto operations simpler.
struct KeyAlgorithmProxy
{
  enum KeyAlgorithmType {
    AES,
    HMAC,
    RSA,
    EC,
    DH,
  };
  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;
  DhKeyAlgorithmStorage mDh;

  // 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;
  }

  bool
  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;
    if (!mRsa.mPublicExponent.Assign(aPublicExponent)) {
      return false;
    }
    return true;
  }

  void
  MakeEc(const nsString& aName, const nsString& aNamedCurve)
  {
    mType = EC;
    mName = aName;
    mEc.mName = aName;
    mEc.mNamedCurve = aNamedCurve;
  }

  bool
  MakeDh(const nsString& aName, const CryptoBuffer& aPrime,
         const CryptoBuffer& aGenerator)
  {
    mType = DH;
    mName = aName;
    mDh.mName = aName;
    if (!mDh.mPrime.Assign(aPrime)) {
      return false;
    }
    if (!mDh.mGenerator.Assign(aGenerator)) {
      return false;
    }
    return true;
  }
};

} // namespace dom
} // namespace mozilla

#endif // mozilla_dom_KeyAlgorithmProxy_h