try/catch WebCrypto, fallback to forge

This commit is contained in:
AJ ONeal 2015-10-23 03:12:20 -07:00
parent 20afbd65b1
commit aa28eaa713
3 changed files with 38 additions and 18 deletions

View File

@ -17,11 +17,11 @@ if (!window.crypto) {
// Generate a key
function generateOtpKey() {
// 20 cryptographically random binary bytes (160-bit key)
if (window.crypto) {
try {
var key = window.crypto.getRandomValues(new Uint8Array(20));
return Promise.resolve(key);
} else {
} catch(e) {
// Promises are supported even in Microsoft Edge
// only old IE and old android need shims
return new Promise(function (resolve, reject) {

View File

@ -12,7 +12,18 @@ exports.sha1Hmac = function (key, bytes) {
var Unibabel = window.Unibabel;
if (window.crypto) {
function useForge() {
var forge = window.forge;
var hmac = forge.hmac.create();
var digest;
hmac.start('sha1', Unibabel.bufferToBinaryString(key));
hmac.update(Unibabel.bufferToBinaryString(bytes));
digest = hmac.digest().toHex();
return window.Promise.resolve(digest);
}
function useWebCrypto() {
return (window.crypto.subtle||window.crypto.webkitSubtle).importKey(
"raw"
, key.buffer
@ -52,15 +63,29 @@ exports.sha1Hmac = function (key, bytes) {
});
});
}
else if (window.forge) {
var forge = window.forge;
var hmac = forge.hmac.create();
var digest;
hmac.start('sha1', Unibabel.bufferToBinaryString(key));
hmac.update(Unibabel.bufferToBinaryString(bytes));
digest = hmac.digest().toHex();
return window.Promise.resolve(digest);
if (window.crypto) {
// WebCrypto is so unreliable right now... ugh...
try {
return useWebCrypto().then(function (result) {
return result;
}, function (err) {
console.warn(err);
console.warn(err.stack);
console.warn("WebCrypto failed, trying forge.js");
return useForge();
});
} catch(e) {
console.warn(e);
console.warn(e.stack);
console.warn("WebCrypto threw exception, trying forge.js");
return useForge();
}
}
else if (window.forge) {
return useForge();
}
else {
throw new Error("WebCrypto or forge.js is required to create a sha1 hmac");

View File

@ -95,7 +95,6 @@ exports.base32ToBuffer = function(encoded) {
} else {
decoded = new Array(len);
}
console.log('debug mobile safari: decoded', decoded);
/* byte by byte isn't as pretty as octet by octet but tests a bit
faster. will have to revisit. */
@ -133,13 +132,9 @@ exports.base32ToBuffer = function(encoded) {
}
}
console.log('debug mobile safari: decoded 2', decoded);
if (decoded.slice) {
console.log('debug mobile safari: decoded 3a', decoded);
if (decoded.slice) { // Array or TypedArray
return decoded.slice(0, plainPos);
} else {
console.log('debug mobile safari: decoded 3b', decoded);
// Mobile Safari's Uint8Array doesn't have slice
} else { // Mobile Safari TypedArray
return new Uint8Array(Array.prototype.slice.call(decoded, 0, plainPos));
}
};