Line data Source code
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 : #include "mozilla/dom/KeyAlgorithmProxy.h"
8 : #include "mozilla/dom/WebCryptoCommon.h"
9 :
10 : namespace mozilla {
11 : namespace dom {
12 :
13 : bool
14 0 : KeyAlgorithmProxy::WriteStructuredClone(JSStructuredCloneWriter* aWriter) const
15 : {
16 0 : if (!WriteString(aWriter, mName) ||
17 0 : !JS_WriteUint32Pair(aWriter, mType, KEY_ALGORITHM_SC_VERSION)) {
18 0 : return false;
19 : }
20 :
21 0 : switch (mType) {
22 : case AES:
23 0 : return JS_WriteUint32Pair(aWriter, mAes.mLength, 0);
24 : case HMAC:
25 0 : return JS_WriteUint32Pair(aWriter, mHmac.mLength, 0) &&
26 0 : WriteString(aWriter, mHmac.mHash.mName);
27 : case RSA: {
28 0 : return JS_WriteUint32Pair(aWriter, mRsa.mModulusLength, 0) &&
29 0 : WriteBuffer(aWriter, mRsa.mPublicExponent) &&
30 0 : WriteString(aWriter, mRsa.mHash.mName);
31 : }
32 : case EC:
33 0 : return WriteString(aWriter, mEc.mNamedCurve);
34 : case DH: {
35 0 : return WriteBuffer(aWriter, mDh.mPrime) &&
36 0 : WriteBuffer(aWriter, mDh.mGenerator);
37 : }
38 : }
39 :
40 0 : return false;
41 : }
42 :
43 : bool
44 0 : KeyAlgorithmProxy::ReadStructuredClone(JSStructuredCloneReader* aReader)
45 : {
46 : uint32_t type, version, dummy;
47 0 : if (!ReadString(aReader, mName) ||
48 0 : !JS_ReadUint32Pair(aReader, &type, &version)) {
49 0 : return false;
50 : }
51 :
52 0 : if (version != KEY_ALGORITHM_SC_VERSION) {
53 0 : return false;
54 : }
55 :
56 0 : mType = (KeyAlgorithmType) type;
57 0 : switch (mType) {
58 : case AES: {
59 : uint32_t length;
60 0 : if (!JS_ReadUint32Pair(aReader, &length, &dummy)) {
61 0 : return false;
62 : }
63 :
64 0 : mAes.mLength = length;
65 0 : mAes.mName = mName;
66 0 : return true;
67 : }
68 : case HMAC: {
69 0 : if (!JS_ReadUint32Pair(aReader, &mHmac.mLength, &dummy) ||
70 0 : !ReadString(aReader, mHmac.mHash.mName)) {
71 0 : return false;
72 : }
73 :
74 0 : mHmac.mName = mName;
75 0 : return true;
76 : }
77 : case RSA: {
78 : uint32_t modulusLength;
79 0 : nsString hashName;
80 0 : if (!JS_ReadUint32Pair(aReader, &modulusLength, &dummy) ||
81 0 : !ReadBuffer(aReader, mRsa.mPublicExponent) ||
82 0 : !ReadString(aReader, mRsa.mHash.mName)) {
83 0 : return false;
84 : }
85 :
86 0 : mRsa.mModulusLength = modulusLength;
87 0 : mRsa.mName = mName;
88 0 : return true;
89 : }
90 : case EC: {
91 0 : nsString namedCurve;
92 0 : if (!ReadString(aReader, mEc.mNamedCurve)) {
93 0 : return false;
94 : }
95 :
96 0 : mEc.mName = mName;
97 0 : return true;
98 : }
99 : case DH: {
100 0 : if (!ReadBuffer(aReader, mDh.mPrime) ||
101 0 : !ReadBuffer(aReader, mDh.mGenerator)) {
102 0 : return false;
103 : }
104 :
105 0 : mDh.mName = mName;
106 0 : return true;
107 : }
108 : }
109 :
110 0 : return false;
111 : }
112 :
113 : CK_MECHANISM_TYPE
114 0 : KeyAlgorithmProxy::Mechanism() const
115 : {
116 0 : if (mType == HMAC) {
117 0 : return GetMechanism(mHmac);
118 : }
119 0 : return MapAlgorithmNameToMechanism(mName);
120 : }
121 :
122 : nsString
123 0 : KeyAlgorithmProxy::JwkAlg() const
124 : {
125 0 : if (mName.EqualsLiteral(WEBCRYPTO_ALG_AES_CBC)) {
126 0 : switch (mAes.mLength) {
127 0 : case 128: return NS_LITERAL_STRING(JWK_ALG_A128CBC);
128 0 : case 192: return NS_LITERAL_STRING(JWK_ALG_A192CBC);
129 0 : case 256: return NS_LITERAL_STRING(JWK_ALG_A256CBC);
130 : }
131 : }
132 :
133 0 : if (mName.EqualsLiteral(WEBCRYPTO_ALG_AES_CTR)) {
134 0 : switch (mAes.mLength) {
135 0 : case 128: return NS_LITERAL_STRING(JWK_ALG_A128CTR);
136 0 : case 192: return NS_LITERAL_STRING(JWK_ALG_A192CTR);
137 0 : case 256: return NS_LITERAL_STRING(JWK_ALG_A256CTR);
138 : }
139 : }
140 :
141 0 : if (mName.EqualsLiteral(WEBCRYPTO_ALG_AES_GCM)) {
142 0 : switch (mAes.mLength) {
143 0 : case 128: return NS_LITERAL_STRING(JWK_ALG_A128GCM);
144 0 : case 192: return NS_LITERAL_STRING(JWK_ALG_A192GCM);
145 0 : case 256: return NS_LITERAL_STRING(JWK_ALG_A256GCM);
146 : }
147 : }
148 :
149 0 : if (mName.EqualsLiteral(WEBCRYPTO_ALG_AES_KW)) {
150 0 : switch (mAes.mLength) {
151 0 : case 128: return NS_LITERAL_STRING(JWK_ALG_A128KW);
152 0 : case 192: return NS_LITERAL_STRING(JWK_ALG_A192KW);
153 0 : case 256: return NS_LITERAL_STRING(JWK_ALG_A256KW);
154 : }
155 : }
156 :
157 0 : if (mName.EqualsLiteral(WEBCRYPTO_ALG_HMAC)) {
158 0 : nsString hashName = mHmac.mHash.mName;
159 0 : if (hashName.EqualsLiteral(WEBCRYPTO_ALG_SHA1)) {
160 0 : return NS_LITERAL_STRING(JWK_ALG_HS1);
161 0 : } else if (hashName.EqualsLiteral(WEBCRYPTO_ALG_SHA256)) {
162 0 : return NS_LITERAL_STRING(JWK_ALG_HS256);
163 0 : } else if (hashName.EqualsLiteral(WEBCRYPTO_ALG_SHA384)) {
164 0 : return NS_LITERAL_STRING(JWK_ALG_HS384);
165 0 : } else if (hashName.EqualsLiteral(WEBCRYPTO_ALG_SHA512)) {
166 0 : return NS_LITERAL_STRING(JWK_ALG_HS512);
167 : }
168 : }
169 :
170 0 : if (mName.EqualsLiteral(WEBCRYPTO_ALG_RSASSA_PKCS1)) {
171 0 : nsString hashName = mRsa.mHash.mName;
172 0 : if (hashName.EqualsLiteral(WEBCRYPTO_ALG_SHA1)) {
173 0 : return NS_LITERAL_STRING(JWK_ALG_RS1);
174 0 : } else if (hashName.EqualsLiteral(WEBCRYPTO_ALG_SHA256)) {
175 0 : return NS_LITERAL_STRING(JWK_ALG_RS256);
176 0 : } else if (hashName.EqualsLiteral(WEBCRYPTO_ALG_SHA384)) {
177 0 : return NS_LITERAL_STRING(JWK_ALG_RS384);
178 0 : } else if (hashName.EqualsLiteral(WEBCRYPTO_ALG_SHA512)) {
179 0 : return NS_LITERAL_STRING(JWK_ALG_RS512);
180 : }
181 : }
182 :
183 0 : if (mName.EqualsLiteral(WEBCRYPTO_ALG_RSA_OAEP)) {
184 0 : nsString hashName = mRsa.mHash.mName;
185 0 : if (hashName.EqualsLiteral(WEBCRYPTO_ALG_SHA1)) {
186 0 : return NS_LITERAL_STRING(JWK_ALG_RSA_OAEP);
187 0 : } else if (hashName.EqualsLiteral(WEBCRYPTO_ALG_SHA256)) {
188 0 : return NS_LITERAL_STRING(JWK_ALG_RSA_OAEP_256);
189 0 : } else if (hashName.EqualsLiteral(WEBCRYPTO_ALG_SHA384)) {
190 0 : return NS_LITERAL_STRING(JWK_ALG_RSA_OAEP_384);
191 0 : } else if (hashName.EqualsLiteral(WEBCRYPTO_ALG_SHA512)) {
192 0 : return NS_LITERAL_STRING(JWK_ALG_RSA_OAEP_512);
193 : }
194 : }
195 :
196 0 : if (mName.EqualsLiteral(WEBCRYPTO_ALG_RSA_PSS)) {
197 0 : nsString hashName = mRsa.mHash.mName;
198 0 : if (hashName.EqualsLiteral(WEBCRYPTO_ALG_SHA1)) {
199 0 : return NS_LITERAL_STRING(JWK_ALG_PS1);
200 0 : } else if (hashName.EqualsLiteral(WEBCRYPTO_ALG_SHA256)) {
201 0 : return NS_LITERAL_STRING(JWK_ALG_PS256);
202 0 : } else if (hashName.EqualsLiteral(WEBCRYPTO_ALG_SHA384)) {
203 0 : return NS_LITERAL_STRING(JWK_ALG_PS384);
204 0 : } else if (hashName.EqualsLiteral(WEBCRYPTO_ALG_SHA512)) {
205 0 : return NS_LITERAL_STRING(JWK_ALG_PS512);
206 : }
207 : }
208 :
209 0 : return nsString();
210 : }
211 :
212 : CK_MECHANISM_TYPE
213 0 : KeyAlgorithmProxy::GetMechanism(const KeyAlgorithm& aAlgorithm)
214 : {
215 : // For everything but HMAC, the name determines the mechanism
216 : // HMAC is handled by the specialization below
217 0 : return MapAlgorithmNameToMechanism(aAlgorithm.mName);
218 : }
219 :
220 : CK_MECHANISM_TYPE
221 0 : KeyAlgorithmProxy::GetMechanism(const HmacKeyAlgorithm& aAlgorithm)
222 : {
223 : // The use of HmacKeyAlgorithm doesn't completely prevent this
224 : // method from being called with dictionaries that don't really
225 : // represent HMAC key algorithms.
226 0 : MOZ_ASSERT(aAlgorithm.mName.EqualsLiteral(WEBCRYPTO_ALG_HMAC));
227 :
228 : CK_MECHANISM_TYPE hashMech;
229 0 : hashMech = MapAlgorithmNameToMechanism(aAlgorithm.mHash.mName);
230 :
231 0 : switch (hashMech) {
232 0 : case CKM_SHA_1: return CKM_SHA_1_HMAC;
233 0 : case CKM_SHA256: return CKM_SHA256_HMAC;
234 0 : case CKM_SHA384: return CKM_SHA384_HMAC;
235 0 : case CKM_SHA512: return CKM_SHA512_HMAC;
236 : }
237 0 : return UNKNOWN_CK_MECHANISM;
238 : }
239 :
240 : } // namespace dom
241 : } // namespace mozilla
|