Skip to content

Commit f47abe7

Browse files
authored
update: support RSA-PSS in WebCrypto (#171)
1 parent d5971e4 commit f47abe7

File tree

1 file changed

+65
-5
lines changed

1 file changed

+65
-5
lines changed

lib/algorithms/rsassa.js

+65-5
Original file line numberDiff line numberDiff line change
@@ -155,14 +155,20 @@ function rsassaV15VerifyFn(name) {
155155
}
156156

157157
// ### RSA-PSS
158-
// NOTE: no WebCryptoAPI variant -- too many browsers don't
159-
// implement it yet (e.g., Firefox, Safari)
160-
161158
function rsassaPssSignFn(name) {
162159
var md = name.replace("PS", "SHA").toLowerCase(),
163160
hash = name.replace("PS", "SHA-");
164161

165-
return function(key, pdata) {
162+
var alg = {
163+
name: "RSA-PSS",
164+
hash: {
165+
name: hash
166+
},
167+
saltLength: CONSTANTS.HASHLENGTH[hash] / 8
168+
};
169+
170+
// ### Fallback implementation -- uses forge
171+
var fallback = function (key, pdata) {
166172
// create the digest
167173
var digest = forge.md[md].create();
168174
digest.start();
@@ -185,14 +191,43 @@ function rsassaPssSignFn(name) {
185191
mac: sig
186192
});
187193
};
194+
195+
// ### WebCryptoAPI Implementation
196+
var webcrypto = function(key, pdata) {
197+
key = rsaUtil.convertToJWK(key, false);
198+
var promise;
199+
promise = helpers.subtleCrypto.importKey("jwk", key, alg, true, ["sign"]);
200+
promise = promise.then(function (key) {
201+
return helpers.subtleCrypto.sign(alg, key, pdata);
202+
});
203+
promise = promise.then(function (result) {
204+
var sig = new Buffer(result);
205+
return {
206+
data: pdata,
207+
mac: sig
208+
};
209+
});
210+
211+
return promise;
212+
};
213+
214+
return helpers.setupFallback(null, webcrypto, fallback);
188215
}
189216

190217
function rsassaPssVerifyFn(name) {
191218
var md = name.replace("PS", "SHA").toLowerCase(),
192219
hash = name.replace("PS", "SHA-");
193220

221+
var alg = {
222+
name: "RSA-PSS",
223+
hash: {
224+
name: hash
225+
},
226+
saltLength: CONSTANTS.HASHLENGTH[hash] / 8
227+
};
228+
194229
// ### Fallback implementation -- uses forge
195-
return function(key, pdata, mac) {
230+
var fallback = function (key, pdata, mac) {
196231
// create the digest
197232
var digest = forge.md[md].create();
198233
digest.start();
@@ -219,6 +254,31 @@ function rsassaPssVerifyFn(name) {
219254
valid: true
220255
});
221256
};
257+
258+
// ### WebCryptoAPI Implementation
259+
var webcrypto = function(key, pdata, mac) {
260+
key = rsaUtil.convertToJWK(key, true);
261+
var promise;
262+
promise = helpers.subtleCrypto.importKey("jwk", key, alg, true, ["verify"]);
263+
promise = promise.then(function (key) {
264+
return helpers.subtleCrypto.verify(alg, key, mac, pdata);
265+
});
266+
promise = promise.then(function (result) {
267+
if (!result) {
268+
return Promise.reject(new Error("verification failed"));
269+
}
270+
271+
return {
272+
data: pdata,
273+
mac: mac,
274+
valid: true
275+
};
276+
});
277+
278+
return promise;
279+
};
280+
281+
return helpers.setupFallback(null, webcrypto, fallback);
222282
}
223283

224284
// ### Public API

0 commit comments

Comments
 (0)