-
Notifications
You must be signed in to change notification settings - Fork 131
Expand file tree
/
Copy pathhelpers.js
More file actions
150 lines (126 loc) · 3.28 KB
/
helpers.js
File metadata and controls
150 lines (126 loc) · 3.28 KB
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
/*!
* algorithms/helpers.js - Internal functions and fields used in Cryptographic
* Algorithms
*
* Copyright (c) 2015 Cisco Systems, Inc. See LICENSE file.
*/
"use strict";
if (typeof Promise === "undefined") {
require("es6-promise").polyfill();
}
// ###
exports.int32ToBuffer = function(v, b) {
b = b || Buffer.alloc(4);
b[0] = (v >>> 24) & 0xff;
b[1] = (v >>> 16) & 0xff;
b[2] = (v >>> 8) & 0xff;
b[3] = v & 0xff;
return b;
};
var MAX_INT32 = Math.pow(2, 32);
exports.int64ToBuffer = function(v, b) {
b = b || Buffer.alloc(8);
var hi = Math.floor(v / MAX_INT32),
lo = v % MAX_INT32;
hi = exports.int32ToBuffer(hi);
lo = exports.int32ToBuffer(lo);
b = Buffer.concat([hi, lo]);
return b;
};
// ### crypto and DOMException in browsers ###
/* global crypto:false, DOMException:false */
function getCryptoSubtle() {
if ("undefined" !== typeof crypto) {
if ("undefined" !== typeof crypto.subtle) {
return crypto.subtle;
}
}
return undefined;
}
function getCryptoNodeJS() {
var crypto;
try {
crypto = require("crypto-browserify");
} catch (err) {
return undefined;
}
if (!Object.keys(crypto).length) {
// treat empty the same as missing
return undefined;
}
return crypto;
}
var supported = {};
Object.defineProperty(exports, "subtleCrypto", {
get: function() {
var result;
if ("subtleCrypto" in supported) {
result = supported.subtleCrypto;
} else {
result = supported.subtleCrypto = getCryptoSubtle();
}
return result;
},
enumerable: true
});
Object.defineProperty(exports, "nodeCrypto", {
get: function() {
var result;
if ("nodeCrypto" in supported) {
result = supported.nodeCrypto;
} else {
result = supported.nodeCrypto = getCryptoNodeJS();
}
return result;
},
enumerable: true
});
exports.setupFallback = function(nodejs, webcrypto, fallback) {
var impl;
if (nodejs && exports.nodeCrypto) {
impl = function main() {
var args = arguments,
promise;
function check(err) {
if (0 === err.message.indexOf("unsupported algorithm:")) {
impl = fallback;
return impl.apply(null, args);
}
return Promise.reject(err);
}
try {
promise = Promise.resolve(nodejs.apply(null, args));
} catch(err) {
promise = check(err);
}
return promise;
};
} else if (webcrypto && exports.subtleCrypto) {
impl = function main() {
var args = arguments,
promise;
function check(err) {
if (err.code === DOMException.NOT_SUPPORTED_ERR ||
// Firefox rejects some operations erroneously complaining about inputs
err.message === "Only ArrayBuffer and ArrayBufferView objects can be passed as CryptoOperationData" ||
// MS Edge rejects with not an Error
!(err instanceof Error)) {
// not actually supported -- always use fallback
impl = fallback;
return impl.apply(null, args);
}
return Promise.reject(err);
}
try {
promise = webcrypto.apply(null, args);
promise = promise.catch(check);
} catch(err) {
promise = check(err);
}
return promise;
};
} else {
impl = fallback;
}
return impl;
};