try/catch WebCrypto, fallback to forge
This commit is contained in:
parent
20afbd65b1
commit
aa28eaa713
|
@ -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) {
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue