@azure/msal-browser 2.28.2 → 2.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/_virtual/_tslib.js +1 -1
- package/dist/app/ClientApplication.d.ts +19 -10
- package/dist/app/ClientApplication.d.ts.map +1 -1
- package/dist/app/ClientApplication.js +67 -66
- package/dist/app/ClientApplication.js.map +1 -1
- package/dist/app/IPublicClientApplication.js +1 -1
- package/dist/app/PublicClientApplication.d.ts.map +1 -1
- package/dist/app/PublicClientApplication.js +37 -10
- package/dist/app/PublicClientApplication.js.map +1 -1
- package/dist/broker/nativeBroker/NativeMessageHandler.js +1 -1
- package/dist/cache/AsyncMemoryStorage.d.ts +7 -2
- package/dist/cache/AsyncMemoryStorage.d.ts.map +1 -1
- package/dist/cache/AsyncMemoryStorage.js +19 -15
- package/dist/cache/AsyncMemoryStorage.js.map +1 -1
- package/dist/cache/BrowserCacheManager.js +1 -1
- package/dist/cache/BrowserStorage.js +1 -1
- package/dist/cache/CryptoKeyStore.d.ts +18 -0
- package/dist/cache/CryptoKeyStore.d.ts.map +1 -0
- package/dist/cache/CryptoKeyStore.js +58 -0
- package/dist/cache/CryptoKeyStore.js.map +1 -0
- package/dist/cache/DatabaseStorage.d.ts.map +1 -1
- package/dist/cache/DatabaseStorage.js +10 -22
- package/dist/cache/DatabaseStorage.js.map +1 -1
- package/dist/cache/MemoryStorage.js +1 -1
- package/dist/cache/TokenCache.js +1 -1
- package/dist/config/Configuration.d.ts +16 -0
- package/dist/config/Configuration.d.ts.map +1 -1
- package/dist/config/Configuration.js +5 -2
- package/dist/config/Configuration.js.map +1 -1
- package/dist/crypto/BrowserCrypto.d.ts +19 -59
- package/dist/crypto/BrowserCrypto.d.ts.map +1 -1
- package/dist/crypto/BrowserCrypto.js +65 -180
- package/dist/crypto/BrowserCrypto.js.map +1 -1
- package/dist/crypto/CryptoOps.d.ts +2 -13
- package/dist/crypto/CryptoOps.d.ts.map +1 -1
- package/dist/crypto/CryptoOps.js +10 -40
- package/dist/crypto/CryptoOps.js.map +1 -1
- package/dist/crypto/GuidGenerator.js +1 -1
- package/dist/crypto/ISubtleCrypto.d.ts +10 -0
- package/dist/crypto/ISubtleCrypto.d.ts.map +1 -0
- package/dist/crypto/ModernBrowserCrypto.d.ts +10 -0
- package/dist/crypto/ModernBrowserCrypto.d.ts.map +1 -0
- package/dist/crypto/ModernBrowserCrypto.js +55 -0
- package/dist/crypto/ModernBrowserCrypto.js.map +1 -0
- package/dist/crypto/MsBrowserCrypto.d.ts +10 -0
- package/dist/crypto/MsBrowserCrypto.d.ts.map +1 -0
- package/dist/crypto/MsBrowserCrypto.js +112 -0
- package/dist/crypto/MsBrowserCrypto.js.map +1 -0
- package/dist/crypto/MsrBrowserCrypto.d.ts +18 -0
- package/dist/crypto/MsrBrowserCrypto.d.ts.map +1 -0
- package/dist/crypto/MsrBrowserCrypto.js +59 -0
- package/dist/crypto/MsrBrowserCrypto.js.map +1 -0
- package/dist/crypto/PkceGenerator.js +1 -1
- package/dist/crypto/SignedHttpRequest.js +1 -1
- package/dist/encode/Base64Decode.js +1 -1
- package/dist/encode/Base64Encode.js +1 -1
- package/dist/error/BrowserAuthError.js +2 -2
- package/dist/error/BrowserAuthError.js.map +1 -1
- package/dist/error/BrowserConfigurationAuthError.d.ts +8 -0
- package/dist/error/BrowserConfigurationAuthError.d.ts.map +1 -1
- package/dist/error/BrowserConfigurationAuthError.js +11 -1
- package/dist/error/BrowserConfigurationAuthError.js.map +1 -1
- package/dist/error/NativeAuthError.js +1 -1
- package/dist/event/EventHandler.js +1 -1
- package/dist/event/EventMessage.js +1 -1
- package/dist/event/EventType.js +1 -1
- package/dist/index.cjs.js +710 -410
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/interaction_client/BaseInteractionClient.js +1 -1
- package/dist/interaction_client/HybridSpaAuthorizationCodeClient.js +1 -1
- package/dist/interaction_client/NativeInteractionClient.d.ts.map +1 -1
- package/dist/interaction_client/NativeInteractionClient.js +3 -2
- package/dist/interaction_client/NativeInteractionClient.js.map +1 -1
- package/dist/interaction_client/PopupClient.js +1 -1
- package/dist/interaction_client/RedirectClient.js +1 -1
- package/dist/interaction_client/SilentAuthCodeClient.js +1 -1
- package/dist/interaction_client/SilentCacheClient.d.ts.map +1 -1
- package/dist/interaction_client/SilentCacheClient.js +1 -1
- package/dist/interaction_client/SilentCacheClient.js.map +1 -1
- package/dist/interaction_client/SilentIframeClient.d.ts +1 -1
- package/dist/interaction_client/SilentIframeClient.d.ts.map +1 -1
- package/dist/interaction_client/SilentIframeClient.js +8 -7
- package/dist/interaction_client/SilentIframeClient.js.map +1 -1
- package/dist/interaction_client/SilentRefreshClient.d.ts.map +1 -1
- package/dist/interaction_client/SilentRefreshClient.js +3 -2
- package/dist/interaction_client/SilentRefreshClient.js.map +1 -1
- package/dist/interaction_client/StandardInteractionClient.js +1 -1
- package/dist/interaction_handler/InteractionHandler.js +1 -1
- package/dist/interaction_handler/RedirectHandler.js +1 -1
- package/dist/interaction_handler/SilentHandler.js +1 -1
- package/dist/internals.js +1 -1
- package/dist/navigation/NavigationClient.js +1 -1
- package/dist/network/FetchClient.js +1 -1
- package/dist/network/XhrClient.js +1 -1
- package/dist/packageMetadata.d.ts +1 -1
- package/dist/packageMetadata.js +2 -2
- package/dist/packageMetadata.js.map +1 -1
- package/dist/request/PopupRequest.d.ts +1 -0
- package/dist/request/PopupRequest.d.ts.map +1 -1
- package/dist/request/RedirectRequest.d.ts +1 -0
- package/dist/request/RedirectRequest.d.ts.map +1 -1
- package/dist/request/SilentRequest.d.ts +9 -2
- package/dist/request/SilentRequest.d.ts.map +1 -1
- package/dist/request/SsoSilentRequest.d.ts +1 -0
- package/dist/request/SsoSilentRequest.d.ts.map +1 -1
- package/dist/telemetry/BrowserPerformanceClient.d.ts +2 -1
- package/dist/telemetry/BrowserPerformanceClient.d.ts.map +1 -1
- package/dist/telemetry/BrowserPerformanceClient.js +3 -3
- package/dist/telemetry/BrowserPerformanceClient.js.map +1 -1
- package/dist/telemetry/BrowserPerformanceMeasurement.js +1 -1
- package/dist/utils/BrowserConstants.d.ts +8 -0
- package/dist/utils/BrowserConstants.d.ts.map +1 -1
- package/dist/utils/BrowserConstants.js +40 -3
- package/dist/utils/BrowserConstants.js.map +1 -1
- package/dist/utils/BrowserProtocolUtils.js +1 -1
- package/dist/utils/BrowserStringUtils.d.ts +5 -0
- package/dist/utils/BrowserStringUtils.d.ts.map +1 -1
- package/dist/utils/BrowserStringUtils.js +8 -1
- package/dist/utils/BrowserStringUtils.js.map +1 -1
- package/dist/utils/BrowserUtils.js +1 -1
- package/dist/utils/MathUtils.js +1 -1
- package/lib/msal-browser.js +710 -410
- package/lib/msal-browser.js.map +1 -1
- package/lib/msal-browser.min.js +37 -37
- package/package.json +2 -2
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
/*! @azure/msal-browser v2.
|
|
1
|
+
/*! @azure/msal-browser v2.29.0 2022-10-03 */
|
|
2
2
|
'use strict';
|
|
3
3
|
import { __awaiter, __generator } from '../_virtual/_tslib.js';
|
|
4
4
|
import { BrowserStringUtils } from '../utils/BrowserStringUtils.js';
|
|
5
5
|
import { BrowserAuthError } from '../error/BrowserAuthError.js';
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
6
|
+
import { ModernBrowserCrypto } from './ModernBrowserCrypto.js';
|
|
7
|
+
import { MsrBrowserCrypto } from './MsrBrowserCrypto.js';
|
|
8
|
+
import { MsBrowserCrypto } from './MsBrowserCrypto.js';
|
|
9
|
+
import { BrowserConfigurationAuthError } from '../error/BrowserConfigurationAuthError.js';
|
|
8
10
|
|
|
9
11
|
/*
|
|
10
12
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -26,18 +28,67 @@ var PUBLIC_EXPONENT = new Uint8Array([0x01, 0x00, 0x01]);
|
|
|
26
28
|
* hashing and encoding. It also has helper functions to validate the availability of specific APIs.
|
|
27
29
|
*/
|
|
28
30
|
var BrowserCrypto = /** @class */ (function () {
|
|
29
|
-
function BrowserCrypto(logger) {
|
|
31
|
+
function BrowserCrypto(logger, cryptoOptions) {
|
|
32
|
+
var _a, _b;
|
|
30
33
|
this.logger = logger;
|
|
31
|
-
|
|
32
|
-
|
|
34
|
+
this.cryptoOptions = cryptoOptions;
|
|
35
|
+
if (this.hasBrowserCrypto()) {
|
|
36
|
+
// Use standard modern web crypto if available
|
|
37
|
+
this.logger.verbose("BrowserCrypto: modern crypto interface available");
|
|
38
|
+
this.subtleCrypto = new ModernBrowserCrypto();
|
|
33
39
|
}
|
|
34
|
-
this.
|
|
40
|
+
else if (this.hasIECrypto()) {
|
|
41
|
+
// For IE11, use msCrypto interface
|
|
42
|
+
this.logger.verbose("BrowserCrypto: MS crypto interface available");
|
|
43
|
+
this.subtleCrypto = new MsBrowserCrypto();
|
|
44
|
+
}
|
|
45
|
+
else if (this.hasMsrCrypto() && ((_a = this.cryptoOptions) === null || _a === void 0 ? void 0 : _a.useMsrCrypto)) {
|
|
46
|
+
// For other browsers, use MSR Crypto if found
|
|
47
|
+
this.logger.verbose("BrowserCrypto: MSR crypto interface available");
|
|
48
|
+
this.subtleCrypto = new MsrBrowserCrypto();
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
if (this.hasMsrCrypto()) {
|
|
52
|
+
this.logger.info("BrowserCrypto: MSR Crypto interface available but system.cryptoOptions.useMsrCrypto not enabled");
|
|
53
|
+
}
|
|
54
|
+
this.logger.error("BrowserCrypto: No crypto interfaces available.");
|
|
55
|
+
throw BrowserAuthError.createCryptoNotAvailableError("Browser crypto, msCrypto, or msrCrypto interfaces not available.");
|
|
56
|
+
}
|
|
57
|
+
// Mainly needed for MSR Crypto: https://github.com/microsoft/MSR-JavaScript-Crypto#random-number-generator-prng
|
|
58
|
+
if (this.subtleCrypto.initPrng) {
|
|
59
|
+
this.logger.verbose("BrowserCrypto: Interface requires entropy");
|
|
60
|
+
if (!((_b = this.cryptoOptions) === null || _b === void 0 ? void 0 : _b.entropy)) {
|
|
61
|
+
this.logger.error("BrowserCrypto: Interface requires entropy but none provided.");
|
|
62
|
+
throw BrowserConfigurationAuthError.createEntropyNotProvided();
|
|
63
|
+
}
|
|
64
|
+
this.logger.verbose("BrowserCrypto: Entropy provided");
|
|
65
|
+
this.subtleCrypto.initPrng(this.cryptoOptions.entropy);
|
|
66
|
+
}
|
|
67
|
+
this.keygenAlgorithmOptions = {
|
|
35
68
|
name: PKCS1_V15_KEYGEN_ALG,
|
|
36
69
|
hash: S256_HASH_ALG,
|
|
37
70
|
modulusLength: MODULUS_LENGTH,
|
|
38
71
|
publicExponent: PUBLIC_EXPONENT
|
|
39
72
|
};
|
|
40
73
|
}
|
|
74
|
+
/**
|
|
75
|
+
* Check whether IE crypto or other browser cryptography is available.
|
|
76
|
+
*/
|
|
77
|
+
BrowserCrypto.prototype.hasIECrypto = function () {
|
|
78
|
+
return "msCrypto" in window;
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* Check whether browser crypto is available.
|
|
82
|
+
*/
|
|
83
|
+
BrowserCrypto.prototype.hasBrowserCrypto = function () {
|
|
84
|
+
return "crypto" in window;
|
|
85
|
+
};
|
|
86
|
+
/**
|
|
87
|
+
* Check whether MSR crypto polyfill is available
|
|
88
|
+
*/
|
|
89
|
+
BrowserCrypto.prototype.hasMsrCrypto = function () {
|
|
90
|
+
return "msrCrypto" in window;
|
|
91
|
+
};
|
|
41
92
|
/**
|
|
42
93
|
* Returns a sha-256 hash of the given dataString as an ArrayBuffer.
|
|
43
94
|
* @param dataString
|
|
@@ -47,7 +98,8 @@ var BrowserCrypto = /** @class */ (function () {
|
|
|
47
98
|
var data;
|
|
48
99
|
return __generator(this, function (_a) {
|
|
49
100
|
data = BrowserStringUtils.stringToUtf8Arr(dataString);
|
|
50
|
-
|
|
101
|
+
// MSR Crypto wants object with name property, instead of string
|
|
102
|
+
return [2 /*return*/, this.subtleCrypto.digest({ name: S256_HASH_ALG }, data)];
|
|
51
103
|
});
|
|
52
104
|
});
|
|
53
105
|
};
|
|
@@ -56,11 +108,7 @@ var BrowserCrypto = /** @class */ (function () {
|
|
|
56
108
|
* @param dataBuffer
|
|
57
109
|
*/
|
|
58
110
|
BrowserCrypto.prototype.getRandomValues = function (dataBuffer) {
|
|
59
|
-
|
|
60
|
-
if (!cryptoObj.getRandomValues) {
|
|
61
|
-
throw BrowserAuthError.createCryptoNotAvailableError("getRandomValues does not exist.");
|
|
62
|
-
}
|
|
63
|
-
cryptoObj.getRandomValues(dataBuffer);
|
|
111
|
+
return this.subtleCrypto.getRandomValues(dataBuffer);
|
|
64
112
|
};
|
|
65
113
|
/**
|
|
66
114
|
* Generates a keypair based on current keygen algorithm config.
|
|
@@ -70,9 +118,7 @@ var BrowserCrypto = /** @class */ (function () {
|
|
|
70
118
|
BrowserCrypto.prototype.generateKeyPair = function (extractable, usages) {
|
|
71
119
|
return __awaiter(this, void 0, void 0, function () {
|
|
72
120
|
return __generator(this, function (_a) {
|
|
73
|
-
return [2 /*return*/, (this.
|
|
74
|
-
this.msCryptoGenerateKey(extractable, usages)
|
|
75
|
-
: window.crypto.subtle.generateKey(this._keygenAlgorithmOptions, extractable, usages))];
|
|
121
|
+
return [2 /*return*/, this.subtleCrypto.generateKey(this.keygenAlgorithmOptions, extractable, usages)];
|
|
76
122
|
});
|
|
77
123
|
});
|
|
78
124
|
};
|
|
@@ -84,7 +130,7 @@ var BrowserCrypto = /** @class */ (function () {
|
|
|
84
130
|
BrowserCrypto.prototype.exportJwk = function (key) {
|
|
85
131
|
return __awaiter(this, void 0, void 0, function () {
|
|
86
132
|
return __generator(this, function (_a) {
|
|
87
|
-
return [2 /*return*/, this.
|
|
133
|
+
return [2 /*return*/, this.subtleCrypto.exportKey(key)];
|
|
88
134
|
});
|
|
89
135
|
});
|
|
90
136
|
};
|
|
@@ -97,13 +143,8 @@ var BrowserCrypto = /** @class */ (function () {
|
|
|
97
143
|
*/
|
|
98
144
|
BrowserCrypto.prototype.importJwk = function (key, extractable, usages) {
|
|
99
145
|
return __awaiter(this, void 0, void 0, function () {
|
|
100
|
-
var keyString, keyBuffer;
|
|
101
146
|
return __generator(this, function (_a) {
|
|
102
|
-
|
|
103
|
-
keyBuffer = BrowserStringUtils.stringToArrayBuffer(keyString);
|
|
104
|
-
return [2 /*return*/, this.hasIECrypto() ?
|
|
105
|
-
this.msCryptoImportKey(keyBuffer, extractable, usages)
|
|
106
|
-
: window.crypto.subtle.importKey(KEY_FORMAT_JWK, key, this._keygenAlgorithmOptions, extractable, usages)];
|
|
147
|
+
return [2 /*return*/, this.subtleCrypto.importKey(key, this.keygenAlgorithmOptions, extractable, usages)];
|
|
107
148
|
});
|
|
108
149
|
});
|
|
109
150
|
};
|
|
@@ -115,166 +156,10 @@ var BrowserCrypto = /** @class */ (function () {
|
|
|
115
156
|
BrowserCrypto.prototype.sign = function (key, data) {
|
|
116
157
|
return __awaiter(this, void 0, void 0, function () {
|
|
117
158
|
return __generator(this, function (_a) {
|
|
118
|
-
return [2 /*return*/, this.
|
|
119
|
-
this.msCryptoSign(key, data)
|
|
120
|
-
: window.crypto.subtle.sign(this._keygenAlgorithmOptions, key, data)];
|
|
121
|
-
});
|
|
122
|
-
});
|
|
123
|
-
};
|
|
124
|
-
/**
|
|
125
|
-
* Check whether IE crypto or other browser cryptography is available.
|
|
126
|
-
*/
|
|
127
|
-
BrowserCrypto.prototype.hasCryptoAPI = function () {
|
|
128
|
-
return this.hasIECrypto() || this.hasBrowserCrypto();
|
|
129
|
-
};
|
|
130
|
-
/**
|
|
131
|
-
* Checks whether IE crypto (AKA msCrypto) is available.
|
|
132
|
-
*/
|
|
133
|
-
BrowserCrypto.prototype.hasIECrypto = function () {
|
|
134
|
-
return "msCrypto" in window;
|
|
135
|
-
};
|
|
136
|
-
/**
|
|
137
|
-
* Check whether browser crypto is available.
|
|
138
|
-
*/
|
|
139
|
-
BrowserCrypto.prototype.hasBrowserCrypto = function () {
|
|
140
|
-
return "crypto" in window;
|
|
141
|
-
};
|
|
142
|
-
/**
|
|
143
|
-
* Helper function for SHA digest.
|
|
144
|
-
* @param algorithm
|
|
145
|
-
* @param data
|
|
146
|
-
*/
|
|
147
|
-
BrowserCrypto.prototype.getSubtleCryptoDigest = function (algorithm, data) {
|
|
148
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
149
|
-
return __generator(this, function (_a) {
|
|
150
|
-
return [2 /*return*/, window.crypto.subtle.digest(algorithm, data)];
|
|
151
|
-
});
|
|
152
|
-
});
|
|
153
|
-
};
|
|
154
|
-
/**
|
|
155
|
-
* IE Helper function for SHA digest.
|
|
156
|
-
* @param algorithm
|
|
157
|
-
* @param data
|
|
158
|
-
*/
|
|
159
|
-
BrowserCrypto.prototype.getMSCryptoDigest = function (algorithm, data) {
|
|
160
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
161
|
-
return __generator(this, function (_a) {
|
|
162
|
-
return [2 /*return*/, new Promise(function (resolve, reject) {
|
|
163
|
-
var digestOperation = window["msCrypto"].subtle.digest(algorithm, data.buffer);
|
|
164
|
-
digestOperation.addEventListener("complete", function (e) {
|
|
165
|
-
resolve(e.target.result);
|
|
166
|
-
});
|
|
167
|
-
digestOperation.addEventListener("error", function (error) {
|
|
168
|
-
reject(error);
|
|
169
|
-
});
|
|
170
|
-
})];
|
|
171
|
-
});
|
|
172
|
-
});
|
|
173
|
-
};
|
|
174
|
-
/**
|
|
175
|
-
* IE Helper function for generating a keypair
|
|
176
|
-
* @param extractable
|
|
177
|
-
* @param usages
|
|
178
|
-
*/
|
|
179
|
-
BrowserCrypto.prototype.msCryptoGenerateKey = function (extractable, usages) {
|
|
180
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
181
|
-
var _this = this;
|
|
182
|
-
return __generator(this, function (_a) {
|
|
183
|
-
return [2 /*return*/, new Promise(function (resolve, reject) {
|
|
184
|
-
var msGenerateKey = window["msCrypto"].subtle.generateKey(_this._keygenAlgorithmOptions, extractable, usages);
|
|
185
|
-
msGenerateKey.addEventListener("complete", function (e) {
|
|
186
|
-
resolve(e.target.result);
|
|
187
|
-
});
|
|
188
|
-
msGenerateKey.addEventListener("error", function (error) {
|
|
189
|
-
reject(error);
|
|
190
|
-
});
|
|
191
|
-
})];
|
|
192
|
-
});
|
|
193
|
-
});
|
|
194
|
-
};
|
|
195
|
-
/**
|
|
196
|
-
* IE Helper function for exportKey
|
|
197
|
-
* @param key
|
|
198
|
-
* @param format
|
|
199
|
-
*/
|
|
200
|
-
BrowserCrypto.prototype.msCryptoExportJwk = function (key) {
|
|
201
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
202
|
-
return __generator(this, function (_a) {
|
|
203
|
-
return [2 /*return*/, new Promise(function (resolve, reject) {
|
|
204
|
-
var msExportKey = window["msCrypto"].subtle.exportKey(KEY_FORMAT_JWK, key);
|
|
205
|
-
msExportKey.addEventListener("complete", function (e) {
|
|
206
|
-
var resultBuffer = e.target.result;
|
|
207
|
-
var resultString = BrowserStringUtils.utf8ArrToString(new Uint8Array(resultBuffer))
|
|
208
|
-
.replace(/\r/g, Constants.EMPTY_STRING)
|
|
209
|
-
.replace(/\n/g, Constants.EMPTY_STRING)
|
|
210
|
-
.replace(/\t/g, Constants.EMPTY_STRING)
|
|
211
|
-
.split(" ").join(Constants.EMPTY_STRING)
|
|
212
|
-
.replace("\u0000", Constants.EMPTY_STRING);
|
|
213
|
-
try {
|
|
214
|
-
resolve(JSON.parse(resultString));
|
|
215
|
-
}
|
|
216
|
-
catch (e) {
|
|
217
|
-
reject(e);
|
|
218
|
-
}
|
|
219
|
-
});
|
|
220
|
-
msExportKey.addEventListener("error", function (error) {
|
|
221
|
-
reject(error);
|
|
222
|
-
});
|
|
223
|
-
})];
|
|
159
|
+
return [2 /*return*/, this.subtleCrypto.sign(this.keygenAlgorithmOptions, key, data)];
|
|
224
160
|
});
|
|
225
161
|
});
|
|
226
162
|
};
|
|
227
|
-
/**
|
|
228
|
-
* IE Helper function for importKey
|
|
229
|
-
* @param key
|
|
230
|
-
* @param format
|
|
231
|
-
* @param extractable
|
|
232
|
-
* @param usages
|
|
233
|
-
*/
|
|
234
|
-
BrowserCrypto.prototype.msCryptoImportKey = function (keyBuffer, extractable, usages) {
|
|
235
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
236
|
-
var _this = this;
|
|
237
|
-
return __generator(this, function (_a) {
|
|
238
|
-
return [2 /*return*/, new Promise(function (resolve, reject) {
|
|
239
|
-
var msImportKey = window["msCrypto"].subtle.importKey(KEY_FORMAT_JWK, keyBuffer, _this._keygenAlgorithmOptions, extractable, usages);
|
|
240
|
-
msImportKey.addEventListener("complete", function (e) {
|
|
241
|
-
resolve(e.target.result);
|
|
242
|
-
});
|
|
243
|
-
msImportKey.addEventListener("error", function (error) {
|
|
244
|
-
reject(error);
|
|
245
|
-
});
|
|
246
|
-
})];
|
|
247
|
-
});
|
|
248
|
-
});
|
|
249
|
-
};
|
|
250
|
-
/**
|
|
251
|
-
* IE Helper function for sign JWT
|
|
252
|
-
* @param key
|
|
253
|
-
* @param data
|
|
254
|
-
*/
|
|
255
|
-
BrowserCrypto.prototype.msCryptoSign = function (key, data) {
|
|
256
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
257
|
-
var _this = this;
|
|
258
|
-
return __generator(this, function (_a) {
|
|
259
|
-
return [2 /*return*/, new Promise(function (resolve, reject) {
|
|
260
|
-
var msSign = window["msCrypto"].subtle.sign(_this._keygenAlgorithmOptions, key, data);
|
|
261
|
-
msSign.addEventListener("complete", function (e) {
|
|
262
|
-
resolve(e.target.result);
|
|
263
|
-
});
|
|
264
|
-
msSign.addEventListener("error", function (error) {
|
|
265
|
-
reject(error);
|
|
266
|
-
});
|
|
267
|
-
})];
|
|
268
|
-
});
|
|
269
|
-
});
|
|
270
|
-
};
|
|
271
|
-
/**
|
|
272
|
-
* Returns stringified jwk.
|
|
273
|
-
* @param jwk
|
|
274
|
-
*/
|
|
275
|
-
BrowserCrypto.getJwkString = function (jwk) {
|
|
276
|
-
return JSON.stringify(jwk, Object.keys(jwk).sort());
|
|
277
|
-
};
|
|
278
163
|
return BrowserCrypto;
|
|
279
164
|
}());
|
|
280
165
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BrowserCrypto.js","sources":["../../src/crypto/BrowserCrypto.ts"],"sourcesContent":["/*\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { BrowserStringUtils } from \"../utils/BrowserStringUtils\";\nimport { BrowserAuthError } from \"../error/BrowserAuthError\";\nimport { KEY_FORMAT_JWK } from \"../utils/BrowserConstants\";\nimport { Logger } from \"..\";\nimport { Constants } from \"@azure/msal-common\";\n/**\n * See here for more info on RsaHashedKeyGenParams: https://developer.mozilla.org/en-US/docs/Web/API/RsaHashedKeyGenParams\n */\n// RSA KeyGen Algorithm\nconst PKCS1_V15_KEYGEN_ALG = \"RSASSA-PKCS1-v1_5\";\n// SHA-256 hashing algorithm\nconst S256_HASH_ALG = \"SHA-256\";\n// MOD length for PoP tokens\nconst MODULUS_LENGTH = 2048;\n// Public Exponent\nconst PUBLIC_EXPONENT: Uint8Array = new Uint8Array([0x01, 0x00, 0x01]);\n\n/**\n * This class implements functions used by the browser library to perform cryptography operations such as\n * hashing and encoding. It also has helper functions to validate the availability of specific APIs.\n */\nexport class BrowserCrypto {\n\n private _keygenAlgorithmOptions: RsaHashedKeyGenParams;\n private logger: Logger;\n\n constructor(logger: Logger) {\n this.logger = logger;\n \n if (!(this.hasCryptoAPI())) {\n throw BrowserAuthError.createCryptoNotAvailableError(\"Browser crypto or msCrypto object not available.\");\n }\n\n this._keygenAlgorithmOptions = {\n name: PKCS1_V15_KEYGEN_ALG,\n hash: S256_HASH_ALG,\n modulusLength: MODULUS_LENGTH,\n publicExponent: PUBLIC_EXPONENT\n };\n }\n\n /**\n * Returns a sha-256 hash of the given dataString as an ArrayBuffer.\n * @param dataString \n */\n async sha256Digest(dataString: string): Promise<ArrayBuffer> {\n const data = BrowserStringUtils.stringToUtf8Arr(dataString);\n\n return this.hasIECrypto() ? this.getMSCryptoDigest(S256_HASH_ALG, data) : this.getSubtleCryptoDigest(S256_HASH_ALG, data);\n }\n\n /**\n * Populates buffer with cryptographically random values.\n * @param dataBuffer \n */\n getRandomValues(dataBuffer: Uint8Array): void {\n const cryptoObj = window[\"msCrypto\"] || window.crypto;\n if (!cryptoObj.getRandomValues) {\n throw BrowserAuthError.createCryptoNotAvailableError(\"getRandomValues does not exist.\");\n }\n cryptoObj.getRandomValues(dataBuffer);\n }\n\n /**\n * Generates a keypair based on current keygen algorithm config.\n * @param extractable \n * @param usages \n */\n async generateKeyPair(extractable: boolean, usages: Array<KeyUsage>): Promise<CryptoKeyPair> {\n return (\n this.hasIECrypto() ? \n this.msCryptoGenerateKey(extractable, usages) \n : window.crypto.subtle.generateKey(this._keygenAlgorithmOptions, extractable, usages)\n ) as Promise<CryptoKeyPair>;\n }\n\n /**\n * Export key as Json Web Key (JWK)\n * @param key \n * @param format \n */\n async exportJwk(key: CryptoKey): Promise<JsonWebKey> {\n return this.hasIECrypto() ? this.msCryptoExportJwk(key) : window.crypto.subtle.exportKey(KEY_FORMAT_JWK, key);\n }\n\n /**\n * Imports key as Json Web Key (JWK), can set extractable and usages.\n * @param key \n * @param format \n * @param extractable \n * @param usages \n */\n async importJwk(key: JsonWebKey, extractable: boolean, usages: Array<KeyUsage>): Promise<CryptoKey> {\n const keyString = BrowserCrypto.getJwkString(key);\n const keyBuffer = BrowserStringUtils.stringToArrayBuffer(keyString);\n\n return this.hasIECrypto() ? \n this.msCryptoImportKey(keyBuffer, extractable, usages) \n : window.crypto.subtle.importKey(KEY_FORMAT_JWK, key, this._keygenAlgorithmOptions, extractable, usages);\n }\n\n /**\n * Signs given data with given key\n * @param key \n * @param data \n */\n async sign(key: CryptoKey, data: ArrayBuffer): Promise<ArrayBuffer> {\n return this.hasIECrypto() ?\n this.msCryptoSign(key, data)\n : window.crypto.subtle.sign(this._keygenAlgorithmOptions, key, data);\n }\n\n /**\n * Check whether IE crypto or other browser cryptography is available.\n */\n private hasCryptoAPI(): boolean {\n return this.hasIECrypto() || this.hasBrowserCrypto();\n }\n\n /**\n * Checks whether IE crypto (AKA msCrypto) is available.\n */\n private hasIECrypto(): boolean {\n return \"msCrypto\" in window;\n }\n\n /**\n * Check whether browser crypto is available.\n */\n private hasBrowserCrypto(): boolean {\n return \"crypto\" in window;\n }\n\n /**\n * Helper function for SHA digest.\n * @param algorithm \n * @param data \n */\n private async getSubtleCryptoDigest(algorithm: string, data: Uint8Array): Promise<ArrayBuffer> {\n return window.crypto.subtle.digest(algorithm, data);\n }\n\n /**\n * IE Helper function for SHA digest.\n * @param algorithm \n * @param data \n */\n private async getMSCryptoDigest(algorithm: string, data: Uint8Array): Promise<ArrayBuffer> {\n return new Promise((resolve, reject) => {\n const digestOperation = window[\"msCrypto\"].subtle.digest(algorithm, data.buffer);\n digestOperation.addEventListener(\"complete\", (e: { target: { result: ArrayBuffer | PromiseLike<ArrayBuffer>; }; }) => {\n resolve(e.target.result);\n });\n digestOperation.addEventListener(\"error\", (error: string) => {\n reject(error);\n });\n });\n }\n\n /**\n * IE Helper function for generating a keypair\n * @param extractable \n * @param usages \n */\n private async msCryptoGenerateKey(extractable: boolean, usages: Array<KeyUsage>): Promise<CryptoKeyPair> {\n return new Promise((resolve: Function, reject: Function) => {\n const msGenerateKey = window[\"msCrypto\"].subtle.generateKey(this._keygenAlgorithmOptions, extractable, usages);\n msGenerateKey.addEventListener(\"complete\", (e: { target: { result: CryptoKeyPair | PromiseLike<CryptoKeyPair>; }; }) => {\n resolve(e.target.result);\n });\n\n msGenerateKey.addEventListener(\"error\", (error: string) => {\n reject(error);\n });\n });\n }\n\n /**\n * IE Helper function for exportKey\n * @param key \n * @param format \n */\n private async msCryptoExportJwk(key: CryptoKey): Promise<JsonWebKey> {\n return new Promise((resolve: Function, reject: Function) => {\n const msExportKey = window[\"msCrypto\"].subtle.exportKey(KEY_FORMAT_JWK, key);\n msExportKey.addEventListener(\"complete\", (e: { target: { result: ArrayBuffer; }; }) => {\n const resultBuffer: ArrayBuffer = e.target.result;\n\n const resultString = BrowserStringUtils.utf8ArrToString(new Uint8Array(resultBuffer))\n .replace(/\\r/g, Constants.EMPTY_STRING)\n .replace(/\\n/g, Constants.EMPTY_STRING)\n .replace(/\\t/g, Constants.EMPTY_STRING)\n .split(\" \").join(Constants.EMPTY_STRING)\n .replace(\"\\u0000\", Constants.EMPTY_STRING);\n\n try {\n resolve(JSON.parse(resultString));\n } catch (e) {\n reject(e);\n }\n });\n\n msExportKey.addEventListener(\"error\", (error: string) => {\n reject(error);\n });\n });\n }\n\n /**\n * IE Helper function for importKey\n * @param key \n * @param format \n * @param extractable \n * @param usages \n */\n private async msCryptoImportKey(keyBuffer: ArrayBuffer, extractable: boolean, usages: Array<KeyUsage>): Promise<CryptoKey> {\n return new Promise((resolve: Function, reject: Function) => {\n const msImportKey = window[\"msCrypto\"].subtle.importKey(KEY_FORMAT_JWK, keyBuffer, this._keygenAlgorithmOptions, extractable, usages);\n msImportKey.addEventListener(\"complete\", (e: { target: { result: CryptoKey | PromiseLike<CryptoKey>; }; }) => {\n resolve(e.target.result);\n });\n\n msImportKey.addEventListener(\"error\", (error: string) => {\n reject(error);\n });\n });\n }\n\n /**\n * IE Helper function for sign JWT\n * @param key \n * @param data \n */\n private async msCryptoSign(key: CryptoKey, data: ArrayBuffer): Promise<ArrayBuffer> {\n return new Promise((resolve: Function, reject: Function) => {\n const msSign = window[\"msCrypto\"].subtle.sign(this._keygenAlgorithmOptions, key, data);\n msSign.addEventListener(\"complete\", (e: { target: { result: ArrayBuffer | PromiseLike<ArrayBuffer>; }; }) => {\n resolve(e.target.result);\n });\n\n msSign.addEventListener(\"error\", (error: string) => {\n reject(error);\n });\n });\n }\n\n /**\n * Returns stringified jwk.\n * @param jwk \n */\n static getJwkString(jwk: JsonWebKey): string {\n return JSON.stringify(jwk, Object.keys(jwk).sort());\n }\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"BrowserCrypto.js","sources":["../../src/crypto/BrowserCrypto.ts"],"sourcesContent":["/*\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { BrowserStringUtils } from \"../utils/BrowserStringUtils\";\nimport { BrowserAuthError } from \"../error/BrowserAuthError\";\nimport { ISubtleCrypto } from \"./ISubtleCrypto\";\nimport { ModernBrowserCrypto } from \"./ModernBrowserCrypto\";\nimport { MsrBrowserCrypto } from \"./MsrBrowserCrypto\";\nimport { MsBrowserCrypto } from \"./MsBrowserCrypto\";\nimport { Logger } from \"@azure/msal-common\";\nimport { BrowserConfigurationAuthError } from \"../error/BrowserConfigurationAuthError\";\nimport { CryptoOptions } from \"../config/Configuration\";\n/**\n * See here for more info on RsaHashedKeyGenParams: https://developer.mozilla.org/en-US/docs/Web/API/RsaHashedKeyGenParams\n */\n// RSA KeyGen Algorithm\nconst PKCS1_V15_KEYGEN_ALG = \"RSASSA-PKCS1-v1_5\";\n// SHA-256 hashing algorithm\nconst S256_HASH_ALG = \"SHA-256\";\n// MOD length for PoP tokens\nconst MODULUS_LENGTH = 2048;\n// Public Exponent\nconst PUBLIC_EXPONENT: Uint8Array = new Uint8Array([0x01, 0x00, 0x01]);\n\n/**\n * This class implements functions used by the browser library to perform cryptography operations such as\n * hashing and encoding. It also has helper functions to validate the availability of specific APIs.\n */\nexport class BrowserCrypto {\n\n private keygenAlgorithmOptions: RsaHashedKeyGenParams;\n private subtleCrypto: ISubtleCrypto;\n private logger: Logger;\n private cryptoOptions?: CryptoOptions;\n\n constructor(logger: Logger, cryptoOptions?: CryptoOptions) {\n this.logger = logger;\n this.cryptoOptions = cryptoOptions;\n\n if (this.hasBrowserCrypto()) {\n // Use standard modern web crypto if available\n this.logger.verbose(\"BrowserCrypto: modern crypto interface available\");\n this.subtleCrypto = new ModernBrowserCrypto();\n } else if (this.hasIECrypto()) {\n // For IE11, use msCrypto interface\n this.logger.verbose(\"BrowserCrypto: MS crypto interface available\");\n this.subtleCrypto = new MsBrowserCrypto();\n } else if (this.hasMsrCrypto() && this.cryptoOptions?.useMsrCrypto) {\n // For other browsers, use MSR Crypto if found\n this.logger.verbose(\"BrowserCrypto: MSR crypto interface available\");\n this.subtleCrypto = new MsrBrowserCrypto();\n } else {\n if (this.hasMsrCrypto()) {\n this.logger.info(\"BrowserCrypto: MSR Crypto interface available but system.cryptoOptions.useMsrCrypto not enabled\");\n }\n this.logger.error(\"BrowserCrypto: No crypto interfaces available.\");\n throw BrowserAuthError.createCryptoNotAvailableError(\"Browser crypto, msCrypto, or msrCrypto interfaces not available.\");\n }\n\n // Mainly needed for MSR Crypto: https://github.com/microsoft/MSR-JavaScript-Crypto#random-number-generator-prng\n if (this.subtleCrypto.initPrng) {\n this.logger.verbose(\"BrowserCrypto: Interface requires entropy\");\n\n if (!this.cryptoOptions?.entropy) {\n this.logger.error(\"BrowserCrypto: Interface requires entropy but none provided.\");\n throw BrowserConfigurationAuthError.createEntropyNotProvided();\n }\n\n this.logger.verbose(\"BrowserCrypto: Entropy provided\");\n this.subtleCrypto.initPrng(this.cryptoOptions.entropy);\n }\n\n this.keygenAlgorithmOptions = {\n name: PKCS1_V15_KEYGEN_ALG,\n hash: S256_HASH_ALG,\n modulusLength: MODULUS_LENGTH,\n publicExponent: PUBLIC_EXPONENT\n };\n }\n\n /**\n * Check whether IE crypto or other browser cryptography is available.\n */\n private hasIECrypto(): boolean {\n return \"msCrypto\" in window;\n }\n\n /**\n * Check whether browser crypto is available.\n */\n private hasBrowserCrypto(): boolean {\n return \"crypto\" in window;\n }\n\n /**\n * Check whether MSR crypto polyfill is available\n */\n private hasMsrCrypto(): boolean {\n return \"msrCrypto\" in window;\n }\n\n /**\n * Returns a sha-256 hash of the given dataString as an ArrayBuffer.\n * @param dataString \n */\n async sha256Digest(dataString: string): Promise<ArrayBuffer> {\n const data = BrowserStringUtils.stringToUtf8Arr(dataString);\n // MSR Crypto wants object with name property, instead of string\n return this.subtleCrypto.digest({ name: S256_HASH_ALG }, data);\n }\n\n /**\n * Populates buffer with cryptographically random values.\n * @param dataBuffer \n */\n getRandomValues(dataBuffer: Uint8Array): Uint8Array {\n return this.subtleCrypto.getRandomValues(dataBuffer);\n }\n\n /**\n * Generates a keypair based on current keygen algorithm config.\n * @param extractable \n * @param usages \n */\n async generateKeyPair(extractable: boolean, usages: Array<KeyUsage>): Promise<CryptoKeyPair> {\n return this.subtleCrypto.generateKey(this.keygenAlgorithmOptions, extractable, usages);\n }\n\n /**\n * Export key as Json Web Key (JWK)\n * @param key \n * @param format \n */\n async exportJwk(key: CryptoKey): Promise<JsonWebKey> {\n return this.subtleCrypto.exportKey(key);\n }\n\n /**\n * Imports key as Json Web Key (JWK), can set extractable and usages.\n * @param key \n * @param format \n * @param extractable \n * @param usages \n */\n async importJwk(key: JsonWebKey, extractable: boolean, usages: Array<KeyUsage>): Promise<CryptoKey> {\n return this.subtleCrypto.importKey(key, this.keygenAlgorithmOptions, extractable, usages);\n }\n\n /**\n * Signs given data with given key\n * @param key \n * @param data \n */\n async sign(key: CryptoKey, data: ArrayBuffer): Promise<ArrayBuffer> {\n return this.subtleCrypto.sign(this.keygenAlgorithmOptions, key, data);\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,22 +1,11 @@
|
|
|
1
1
|
import { ICrypto, IPerformanceClient, Logger, PkceCodes, SignedHttpRequest, SignedHttpRequestParameters } from "@azure/msal-common";
|
|
2
|
-
import {
|
|
2
|
+
import { CryptoOptions } from "../config/Configuration";
|
|
3
3
|
export declare type CachedKeyPair = {
|
|
4
4
|
publicKey: CryptoKey;
|
|
5
5
|
privateKey: CryptoKey;
|
|
6
6
|
requestMethod?: string;
|
|
7
7
|
requestUri?: string;
|
|
8
8
|
};
|
|
9
|
-
/**
|
|
10
|
-
* MSAL CryptoKeyStore DB Version 2
|
|
11
|
-
*/
|
|
12
|
-
export declare type CryptoKeyStore = {
|
|
13
|
-
asymmetricKeys: AsyncMemoryStorage<CachedKeyPair>;
|
|
14
|
-
symmetricKeys: AsyncMemoryStorage<CryptoKey>;
|
|
15
|
-
};
|
|
16
|
-
export declare enum CryptoKeyStoreNames {
|
|
17
|
-
asymmetricKeys = "asymmetricKeys",
|
|
18
|
-
symmetricKeys = "symmetricKeys"
|
|
19
|
-
}
|
|
20
9
|
/**
|
|
21
10
|
* This class implements MSAL's crypto interface, which allows it to perform base64 encoding and decoding, generating cryptographically random GUIDs and
|
|
22
11
|
* implementing Proof Key for Code Exchange specs for the OAuth Authorization Code Flow using PKCE (rfc here: https://tools.ietf.org/html/rfc7636).
|
|
@@ -36,7 +25,7 @@ export declare class CryptoOps implements ICrypto {
|
|
|
36
25
|
private static POP_KEY_USAGES;
|
|
37
26
|
private static EXTRACTABLE;
|
|
38
27
|
private cache;
|
|
39
|
-
constructor(logger: Logger, performanceClient?: IPerformanceClient);
|
|
28
|
+
constructor(logger: Logger, performanceClient?: IPerformanceClient, cryptoConfig?: CryptoOptions);
|
|
40
29
|
/**
|
|
41
30
|
* Creates a new random GUID - used to populate state and nonce.
|
|
42
31
|
* @returns string (GUID)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CryptoOps.d.ts","sourceRoot":"","sources":["../../src/crypto/CryptoOps.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,OAAO,EAAE,kBAAkB,EAAc,MAAM,EAAqB,SAAS,EAAE,iBAAiB,EAAE,2BAA2B,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"CryptoOps.d.ts","sourceRoot":"","sources":["../../src/crypto/CryptoOps.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,OAAO,EAAE,kBAAkB,EAAc,MAAM,EAAqB,SAAS,EAAE,iBAAiB,EAAE,2BAA2B,EAAE,MAAM,oBAAoB,CAAC;AASnK,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAExD,oBAAY,aAAa,GAAG;IACxB,SAAS,EAAE,SAAS,CAAC;IACrB,UAAU,EAAE,SAAS,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAA;CACtB,CAAC;AAEF;;;GAGG;AACH,qBAAa,SAAU,YAAW,OAAO;IAErC,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,SAAS,CAAe;IAChC,OAAO,CAAC,SAAS,CAAe;IAChC,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,MAAM,CAAS;IAEvB;;;OAGG;IACH,OAAO,CAAC,iBAAiB,CAAiC;IAE1D,OAAO,CAAC,MAAM,CAAC,cAAc,CAAuC;IACpE,OAAO,CAAC,MAAM,CAAC,WAAW,CAAiB;IAC3C,OAAO,CAAC,KAAK,CAAiB;gBAElB,MAAM,EAAE,MAAM,EAAE,iBAAiB,CAAC,EAAE,kBAAkB,EAAE,YAAY,CAAC,EAAE,aAAa;IAYhG;;;OAGG;IACH,aAAa,IAAI,MAAM;IAIvB;;;OAGG;IACH,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAInC;;;OAGG;IACH,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAInC;;OAEG;IACG,iBAAiB,IAAI,OAAO,CAAC,SAAS,CAAC;IAI7C;;;OAGG;IACG,sBAAsB,CAAC,OAAO,EAAE,2BAA2B,GAAG,OAAO,CAAC,MAAM,CAAC;IA2CnF;;;OAGG;IACG,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAM1D;;OAEG;IACG,aAAa,IAAI,OAAO,CAAC,OAAO,CAAC;IAIvC;;;;OAIG;IACG,OAAO,CAAC,OAAO,EAAE,iBAAiB,EAAE,GAAG,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IA4C/F;;;OAGG;IACG,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAKvD"}
|
package/dist/crypto/CryptoOps.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @azure/msal-browser v2.
|
|
1
|
+
/*! @azure/msal-browser v2.29.0 2022-10-03 */
|
|
2
2
|
'use strict';
|
|
3
3
|
import { __awaiter, __generator } from '../_virtual/_tslib.js';
|
|
4
4
|
import { PerformanceEvents, JoseHeader } from '@azure/msal-common';
|
|
@@ -9,34 +9,26 @@ import { PkceGenerator } from './PkceGenerator.js';
|
|
|
9
9
|
import { BrowserCrypto } from './BrowserCrypto.js';
|
|
10
10
|
import { BrowserStringUtils } from '../utils/BrowserStringUtils.js';
|
|
11
11
|
import { BrowserAuthError } from '../error/BrowserAuthError.js';
|
|
12
|
-
import {
|
|
12
|
+
import { CryptoKeyStore } from '../cache/CryptoKeyStore.js';
|
|
13
13
|
|
|
14
14
|
/*
|
|
15
15
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
16
16
|
* Licensed under the MIT License.
|
|
17
17
|
*/
|
|
18
|
-
var CryptoKeyStoreNames;
|
|
19
|
-
(function (CryptoKeyStoreNames) {
|
|
20
|
-
CryptoKeyStoreNames["asymmetricKeys"] = "asymmetricKeys";
|
|
21
|
-
CryptoKeyStoreNames["symmetricKeys"] = "symmetricKeys";
|
|
22
|
-
})(CryptoKeyStoreNames || (CryptoKeyStoreNames = {}));
|
|
23
18
|
/**
|
|
24
19
|
* This class implements MSAL's crypto interface, which allows it to perform base64 encoding and decoding, generating cryptographically random GUIDs and
|
|
25
20
|
* implementing Proof Key for Code Exchange specs for the OAuth Authorization Code Flow using PKCE (rfc here: https://tools.ietf.org/html/rfc7636).
|
|
26
21
|
*/
|
|
27
22
|
var CryptoOps = /** @class */ (function () {
|
|
28
|
-
function CryptoOps(logger, performanceClient) {
|
|
23
|
+
function CryptoOps(logger, performanceClient, cryptoConfig) {
|
|
29
24
|
this.logger = logger;
|
|
30
25
|
// Browser crypto needs to be validated first before any other classes can be set.
|
|
31
|
-
this.browserCrypto = new BrowserCrypto(this.logger);
|
|
26
|
+
this.browserCrypto = new BrowserCrypto(this.logger, cryptoConfig);
|
|
32
27
|
this.b64Encode = new Base64Encode();
|
|
33
28
|
this.b64Decode = new Base64Decode();
|
|
34
29
|
this.guidGenerator = new GuidGenerator(this.browserCrypto);
|
|
35
30
|
this.pkceGenerator = new PkceGenerator(this.browserCrypto);
|
|
36
|
-
this.cache =
|
|
37
|
-
asymmetricKeys: new AsyncMemoryStorage(this.logger, CryptoKeyStoreNames.asymmetricKeys),
|
|
38
|
-
symmetricKeys: new AsyncMemoryStorage(this.logger, CryptoKeyStoreNames.symmetricKeys)
|
|
39
|
-
};
|
|
31
|
+
this.cache = new CryptoKeyStore(this.logger);
|
|
40
32
|
this.performanceClient = performanceClient;
|
|
41
33
|
}
|
|
42
34
|
/**
|
|
@@ -93,7 +85,7 @@ var CryptoOps = /** @class */ (function () {
|
|
|
93
85
|
kty: publicKeyJwk.kty,
|
|
94
86
|
n: publicKeyJwk.n
|
|
95
87
|
};
|
|
96
|
-
publicJwkString =
|
|
88
|
+
publicJwkString = BrowserStringUtils.getSortedObjectString(pubKeyThumprintObj);
|
|
97
89
|
return [4 /*yield*/, this.hashString(publicJwkString)];
|
|
98
90
|
case 3:
|
|
99
91
|
publicJwkHash = _b.sent();
|
|
@@ -148,32 +140,10 @@ var CryptoOps = /** @class */ (function () {
|
|
|
148
140
|
*/
|
|
149
141
|
CryptoOps.prototype.clearKeystore = function () {
|
|
150
142
|
return __awaiter(this, void 0, void 0, function () {
|
|
151
|
-
var e_1;
|
|
152
143
|
return __generator(this, function (_a) {
|
|
153
144
|
switch (_a.label) {
|
|
154
|
-
case 0:
|
|
155
|
-
|
|
156
|
-
this.logger.verbose("Deleting in-memory and persistent asymmetric key stores");
|
|
157
|
-
return [4 /*yield*/, this.cache.asymmetricKeys.clear()];
|
|
158
|
-
case 1:
|
|
159
|
-
_a.sent();
|
|
160
|
-
this.logger.verbose("Successfully deleted asymmetric key stores");
|
|
161
|
-
this.logger.verbose("Deleting in-memory and persistent symmetric key stores");
|
|
162
|
-
return [4 /*yield*/, this.cache.symmetricKeys.clear()];
|
|
163
|
-
case 2:
|
|
164
|
-
_a.sent();
|
|
165
|
-
this.logger.verbose("Successfully deleted symmetric key stores");
|
|
166
|
-
return [2 /*return*/, true];
|
|
167
|
-
case 3:
|
|
168
|
-
e_1 = _a.sent();
|
|
169
|
-
if (e_1 instanceof Error) {
|
|
170
|
-
this.logger.error("Clearing keystore failed with error: " + e_1.message);
|
|
171
|
-
}
|
|
172
|
-
else {
|
|
173
|
-
this.logger.error("Clearing keystore failed with unknown error");
|
|
174
|
-
}
|
|
175
|
-
return [2 /*return*/, false];
|
|
176
|
-
case 4: return [2 /*return*/];
|
|
145
|
+
case 0: return [4 /*yield*/, this.cache.clear()];
|
|
146
|
+
case 1: return [2 /*return*/, _a.sent()];
|
|
177
147
|
}
|
|
178
148
|
});
|
|
179
149
|
});
|
|
@@ -200,7 +170,7 @@ var CryptoOps = /** @class */ (function () {
|
|
|
200
170
|
return [4 /*yield*/, this.browserCrypto.exportJwk(cachedKeyPair.publicKey)];
|
|
201
171
|
case 2:
|
|
202
172
|
publicKeyJwk = _b.sent();
|
|
203
|
-
publicKeyJwkString =
|
|
173
|
+
publicKeyJwkString = BrowserStringUtils.getSortedObjectString(publicKeyJwk);
|
|
204
174
|
encodedKeyIdThumbprint = this.b64Encode.urlEncode(JSON.stringify({ kid: kid }));
|
|
205
175
|
shrHeader = JoseHeader.getShrHeaderString({ kid: encodedKeyIdThumbprint, alg: publicKeyJwk.alg });
|
|
206
176
|
encodedShrHeader = this.b64Encode.urlEncode(shrHeader);
|
|
@@ -249,5 +219,5 @@ var CryptoOps = /** @class */ (function () {
|
|
|
249
219
|
return CryptoOps;
|
|
250
220
|
}());
|
|
251
221
|
|
|
252
|
-
export {
|
|
222
|
+
export { CryptoOps };
|
|
253
223
|
//# sourceMappingURL=CryptoOps.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CryptoOps.js","sources":["../../src/crypto/CryptoOps.ts"],"sourcesContent":["/*\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ICrypto, IPerformanceClient, JoseHeader, Logger, PerformanceEvents, PkceCodes, SignedHttpRequest, SignedHttpRequestParameters } from \"@azure/msal-common\";\nimport { GuidGenerator } from \"./GuidGenerator\";\nimport { Base64Encode } from \"../encode/Base64Encode\";\nimport { Base64Decode } from \"../encode/Base64Decode\";\nimport { PkceGenerator } from \"./PkceGenerator\";\nimport { BrowserCrypto } from \"./BrowserCrypto\";\nimport { BrowserStringUtils } from \"../utils/BrowserStringUtils\";\nimport { BrowserAuthError } from \"../error/BrowserAuthError\";\nimport { AsyncMemoryStorage } from \"../cache/AsyncMemoryStorage\";\n\nexport type CachedKeyPair = {\n publicKey: CryptoKey,\n privateKey: CryptoKey,\n requestMethod?: string,\n requestUri?: string\n};\n\n/**\n * MSAL CryptoKeyStore DB Version 2\n */\nexport type CryptoKeyStore = {\n asymmetricKeys: AsyncMemoryStorage<CachedKeyPair>;\n symmetricKeys: AsyncMemoryStorage<CryptoKey>;\n};\n\nexport enum CryptoKeyStoreNames {\n asymmetricKeys = \"asymmetricKeys\",\n symmetricKeys = \"symmetricKeys\"\n}\n\n/**\n * This class implements MSAL's crypto interface, which allows it to perform base64 encoding and decoding, generating cryptographically random GUIDs and \n * implementing Proof Key for Code Exchange specs for the OAuth Authorization Code Flow using PKCE (rfc here: https://tools.ietf.org/html/rfc7636).\n */\nexport class CryptoOps implements ICrypto {\n\n private browserCrypto: BrowserCrypto;\n private guidGenerator: GuidGenerator;\n private b64Encode: Base64Encode;\n private b64Decode: Base64Decode;\n private pkceGenerator: PkceGenerator;\n private logger: Logger;\n\n /**\n * CryptoOps can be used in contexts outside a PCA instance,\n * meaning there won't be a performance manager available.\n */\n private performanceClient: IPerformanceClient | undefined;\n\n private static POP_KEY_USAGES: Array<KeyUsage> = [\"sign\", \"verify\"];\n private static EXTRACTABLE: boolean = true;\n private cache: CryptoKeyStore;\n\n constructor(logger: Logger, performanceClient?: IPerformanceClient) {\n this.logger = logger;\n // Browser crypto needs to be validated first before any other classes can be set.\n this.browserCrypto = new BrowserCrypto(this.logger);\n this.b64Encode = new Base64Encode();\n this.b64Decode = new Base64Decode();\n this.guidGenerator = new GuidGenerator(this.browserCrypto);\n this.pkceGenerator = new PkceGenerator(this.browserCrypto);\n this.cache = {\n asymmetricKeys: new AsyncMemoryStorage<CachedKeyPair>(this.logger, CryptoKeyStoreNames.asymmetricKeys),\n symmetricKeys: new AsyncMemoryStorage<CryptoKey>(this.logger, CryptoKeyStoreNames.symmetricKeys)\n };\n this.performanceClient = performanceClient;\n }\n\n /**\n * Creates a new random GUID - used to populate state and nonce.\n * @returns string (GUID)\n */\n createNewGuid(): string {\n return this.guidGenerator.generateGuid();\n }\n\n /**\n * Encodes input string to base64.\n * @param input \n */\n base64Encode(input: string): string {\n return this.b64Encode.encode(input);\n } \n \n /**\n * Decodes input string from base64.\n * @param input \n */\n base64Decode(input: string): string {\n return this.b64Decode.decode(input);\n }\n\n /**\n * Generates PKCE codes used in Authorization Code Flow.\n */\n async generatePkceCodes(): Promise<PkceCodes> {\n return this.pkceGenerator.generateCodes();\n }\n\n /**\n * Generates a keypair, stores it and returns a thumbprint\n * @param request\n */\n async getPublicKeyThumbprint(request: SignedHttpRequestParameters): Promise<string> {\n const publicKeyThumbMeasurement = this.performanceClient?.startMeasurement(PerformanceEvents.CryptoOptsGetPublicKeyThumbprint, request.correlationId);\n\n // Generate Keypair\n const keyPair: CryptoKeyPair = await this.browserCrypto.generateKeyPair(CryptoOps.EXTRACTABLE, CryptoOps.POP_KEY_USAGES);\n\n // Generate Thumbprint for Public Key\n const publicKeyJwk: JsonWebKey = await this.browserCrypto.exportJwk(keyPair.publicKey);\n \n const pubKeyThumprintObj: JsonWebKey = {\n e: publicKeyJwk.e,\n kty: publicKeyJwk.kty,\n n: publicKeyJwk.n\n };\n\n const publicJwkString: string = BrowserCrypto.getJwkString(pubKeyThumprintObj);\n const publicJwkHash = await this.hashString(publicJwkString);\n\n // Generate Thumbprint for Private Key\n const privateKeyJwk: JsonWebKey = await this.browserCrypto.exportJwk(keyPair.privateKey);\n // Re-import private key to make it unextractable\n const unextractablePrivateKey: CryptoKey = await this.browserCrypto.importJwk(privateKeyJwk, false, [\"sign\"]);\n\n // Store Keypair data in keystore\n await this.cache.asymmetricKeys.setItem(\n publicJwkHash, \n {\n privateKey: unextractablePrivateKey,\n publicKey: keyPair.publicKey,\n requestMethod: request.resourceRequestMethod,\n requestUri: request.resourceRequestUri\n }\n );\n\n if (publicKeyThumbMeasurement) {\n publicKeyThumbMeasurement.endMeasurement({\n success: true\n });\n }\n\n return publicJwkHash;\n }\n\n /**\n * Removes cryptographic keypair from key store matching the keyId passed in\n * @param kid \n */\n async removeTokenBindingKey(kid: string): Promise<boolean> {\n await this.cache.asymmetricKeys.removeItem(kid);\n const keyFound = await this.cache.asymmetricKeys.containsKey(kid);\n return !keyFound;\n }\n\n /**\n * Removes all cryptographic keys from IndexedDB storage\n */\n async clearKeystore(): Promise<boolean> {\n try {\n this.logger.verbose(\"Deleting in-memory and persistent asymmetric key stores\");\n await this.cache.asymmetricKeys.clear();\n this.logger.verbose(\"Successfully deleted asymmetric key stores\");\n this.logger.verbose(\"Deleting in-memory and persistent symmetric key stores\");\n await this.cache.symmetricKeys.clear();\n this.logger.verbose(\"Successfully deleted symmetric key stores\");\n return true;\n } catch (e) {\n if (e instanceof Error) {\n this.logger.error(`Clearing keystore failed with error: ${e.message}`);\n } else {\n this.logger.error(\"Clearing keystore failed with unknown error\");\n }\n \n return false;\n }\n }\n\n /**\n * Signs the given object as a jwt payload with private key retrieved by given kid.\n * @param payload \n * @param kid \n */\n async signJwt(payload: SignedHttpRequest, kid: string, correlationId?: string): Promise<string> {\n const signJwtMeasurement = this.performanceClient?.startMeasurement(PerformanceEvents.CryptoOptsSignJwt, correlationId);\n const cachedKeyPair = await this.cache.asymmetricKeys.getItem(kid);\n \n if (!cachedKeyPair) {\n throw BrowserAuthError.createSigningKeyNotFoundInStorageError(kid);\n }\n\n // Get public key as JWK\n const publicKeyJwk = await this.browserCrypto.exportJwk(cachedKeyPair.publicKey);\n const publicKeyJwkString = BrowserCrypto.getJwkString(publicKeyJwk);\n \n // Base64URL encode public key thumbprint with keyId only: BASE64URL({ kid: \"FULL_PUBLIC_KEY_HASH\" })\n const encodedKeyIdThumbprint = this.b64Encode.urlEncode(JSON.stringify({ kid: kid }));\n\n // Generate header\n const shrHeader = JoseHeader.getShrHeaderString({ kid: encodedKeyIdThumbprint, alg: publicKeyJwk.alg });\n const encodedShrHeader = this.b64Encode.urlEncode(shrHeader);\n\n // Generate payload\n payload.cnf = {\n jwk: JSON.parse(publicKeyJwkString)\n };\n const encodedPayload = this.b64Encode.urlEncode(JSON.stringify(payload));\n\n // Form token string\n const tokenString = `${encodedShrHeader}.${encodedPayload}`;\n\n // Sign token\n const tokenBuffer = BrowserStringUtils.stringToArrayBuffer(tokenString);\n const signatureBuffer = await this.browserCrypto.sign(cachedKeyPair.privateKey, tokenBuffer);\n const encodedSignature = this.b64Encode.urlEncodeArr(new Uint8Array(signatureBuffer));\n\n const signedJwt = `${tokenString}.${encodedSignature}`;\n\n if (signJwtMeasurement) {\n signJwtMeasurement.endMeasurement({\n success: true\n });\n }\n\n return signedJwt;\n }\n\n /**\n * Returns the SHA-256 hash of an input string\n * @param plainText\n */\n async hashString(plainText: string): Promise<string> {\n const hashBuffer: ArrayBuffer = await this.browserCrypto.sha256Digest(plainText);\n const hashBytes = new Uint8Array(hashBuffer);\n return this.b64Encode.urlEncodeArr(hashBytes);\n }\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CryptoOps.js","sources":["../../src/crypto/CryptoOps.ts"],"sourcesContent":["/*\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ICrypto, IPerformanceClient, JoseHeader, Logger, PerformanceEvents, PkceCodes, SignedHttpRequest, SignedHttpRequestParameters } from \"@azure/msal-common\";\nimport { GuidGenerator } from \"./GuidGenerator\";\nimport { Base64Encode } from \"../encode/Base64Encode\";\nimport { Base64Decode } from \"../encode/Base64Decode\";\nimport { PkceGenerator } from \"./PkceGenerator\";\nimport { BrowserCrypto } from \"./BrowserCrypto\";\nimport { BrowserStringUtils } from \"../utils/BrowserStringUtils\";\nimport { BrowserAuthError } from \"../error/BrowserAuthError\";\nimport { CryptoKeyStore } from \"../cache/CryptoKeyStore\";\nimport { CryptoOptions } from \"../config/Configuration\";\n\nexport type CachedKeyPair = {\n publicKey: CryptoKey,\n privateKey: CryptoKey,\n requestMethod?: string,\n requestUri?: string\n};\n\n/**\n * This class implements MSAL's crypto interface, which allows it to perform base64 encoding and decoding, generating cryptographically random GUIDs and \n * implementing Proof Key for Code Exchange specs for the OAuth Authorization Code Flow using PKCE (rfc here: https://tools.ietf.org/html/rfc7636).\n */\nexport class CryptoOps implements ICrypto {\n\n private browserCrypto: BrowserCrypto;\n private guidGenerator: GuidGenerator;\n private b64Encode: Base64Encode;\n private b64Decode: Base64Decode;\n private pkceGenerator: PkceGenerator;\n private logger: Logger;\n\n /**\n * CryptoOps can be used in contexts outside a PCA instance,\n * meaning there won't be a performance manager available.\n */\n private performanceClient: IPerformanceClient | undefined;\n\n private static POP_KEY_USAGES: Array<KeyUsage> = [\"sign\", \"verify\"];\n private static EXTRACTABLE: boolean = true;\n private cache: CryptoKeyStore;\n\n constructor(logger: Logger, performanceClient?: IPerformanceClient, cryptoConfig?: CryptoOptions) {\n this.logger = logger;\n // Browser crypto needs to be validated first before any other classes can be set.\n this.browserCrypto = new BrowserCrypto(this.logger, cryptoConfig);\n this.b64Encode = new Base64Encode();\n this.b64Decode = new Base64Decode();\n this.guidGenerator = new GuidGenerator(this.browserCrypto);\n this.pkceGenerator = new PkceGenerator(this.browserCrypto);\n this.cache = new CryptoKeyStore(this.logger);\n this.performanceClient = performanceClient;\n }\n\n /**\n * Creates a new random GUID - used to populate state and nonce.\n * @returns string (GUID)\n */\n createNewGuid(): string {\n return this.guidGenerator.generateGuid();\n }\n\n /**\n * Encodes input string to base64.\n * @param input \n */\n base64Encode(input: string): string {\n return this.b64Encode.encode(input);\n } \n \n /**\n * Decodes input string from base64.\n * @param input \n */\n base64Decode(input: string): string {\n return this.b64Decode.decode(input);\n }\n\n /**\n * Generates PKCE codes used in Authorization Code Flow.\n */\n async generatePkceCodes(): Promise<PkceCodes> {\n return this.pkceGenerator.generateCodes();\n }\n\n /**\n * Generates a keypair, stores it and returns a thumbprint\n * @param request\n */\n async getPublicKeyThumbprint(request: SignedHttpRequestParameters): Promise<string> {\n const publicKeyThumbMeasurement = this.performanceClient?.startMeasurement(PerformanceEvents.CryptoOptsGetPublicKeyThumbprint, request.correlationId);\n\n // Generate Keypair\n const keyPair: CryptoKeyPair = await this.browserCrypto.generateKeyPair(CryptoOps.EXTRACTABLE, CryptoOps.POP_KEY_USAGES);\n\n // Generate Thumbprint for Public Key\n const publicKeyJwk: JsonWebKey = await this.browserCrypto.exportJwk(keyPair.publicKey);\n \n const pubKeyThumprintObj: JsonWebKey = {\n e: publicKeyJwk.e,\n kty: publicKeyJwk.kty,\n n: publicKeyJwk.n\n };\n \n const publicJwkString: string = BrowserStringUtils.getSortedObjectString(pubKeyThumprintObj);\n const publicJwkHash = await this.hashString(publicJwkString);\n\n // Generate Thumbprint for Private Key\n const privateKeyJwk: JsonWebKey = await this.browserCrypto.exportJwk(keyPair.privateKey);\n // Re-import private key to make it unextractable\n const unextractablePrivateKey: CryptoKey = await this.browserCrypto.importJwk(privateKeyJwk, false, [\"sign\"]);\n\n // Store Keypair data in keystore\n await this.cache.asymmetricKeys.setItem(\n publicJwkHash, \n {\n privateKey: unextractablePrivateKey,\n publicKey: keyPair.publicKey,\n requestMethod: request.resourceRequestMethod,\n requestUri: request.resourceRequestUri\n }\n );\n\n if (publicKeyThumbMeasurement) {\n publicKeyThumbMeasurement.endMeasurement({\n success: true\n });\n }\n\n return publicJwkHash;\n }\n\n /**\n * Removes cryptographic keypair from key store matching the keyId passed in\n * @param kid \n */\n async removeTokenBindingKey(kid: string): Promise<boolean> {\n await this.cache.asymmetricKeys.removeItem(kid);\n const keyFound = await this.cache.asymmetricKeys.containsKey(kid);\n return !keyFound;\n }\n\n /**\n * Removes all cryptographic keys from IndexedDB storage\n */\n async clearKeystore(): Promise<boolean> {\n return await this.cache.clear();\n }\n\n /**\n * Signs the given object as a jwt payload with private key retrieved by given kid.\n * @param payload \n * @param kid \n */\n async signJwt(payload: SignedHttpRequest, kid: string, correlationId?: string): Promise<string> {\n const signJwtMeasurement = this.performanceClient?.startMeasurement(PerformanceEvents.CryptoOptsSignJwt, correlationId);\n const cachedKeyPair = await this.cache.asymmetricKeys.getItem(kid);\n \n if (!cachedKeyPair) {\n throw BrowserAuthError.createSigningKeyNotFoundInStorageError(kid);\n }\n\n // Get public key as JWK\n const publicKeyJwk = await this.browserCrypto.exportJwk(cachedKeyPair.publicKey);\n const publicKeyJwkString = BrowserStringUtils.getSortedObjectString(publicKeyJwk);\n\n // Base64URL encode public key thumbprint with keyId only: BASE64URL({ kid: \"FULL_PUBLIC_KEY_HASH\" })\n const encodedKeyIdThumbprint = this.b64Encode.urlEncode(JSON.stringify({ kid: kid }));\n \n // Generate header\n const shrHeader = JoseHeader.getShrHeaderString({ kid: encodedKeyIdThumbprint, alg: publicKeyJwk.alg });\n const encodedShrHeader = this.b64Encode.urlEncode(shrHeader);\n\n // Generate payload\n payload.cnf = {\n jwk: JSON.parse(publicKeyJwkString)\n };\n const encodedPayload = this.b64Encode.urlEncode(JSON.stringify(payload));\n\n // Form token string\n const tokenString = `${encodedShrHeader}.${encodedPayload}`;\n\n // Sign token\n const tokenBuffer = BrowserStringUtils.stringToArrayBuffer(tokenString);\n const signatureBuffer = await this.browserCrypto.sign(cachedKeyPair.privateKey, tokenBuffer);\n const encodedSignature = this.b64Encode.urlEncodeArr(new Uint8Array(signatureBuffer));\n\n const signedJwt = `${tokenString}.${encodedSignature}`;\n\n if (signJwtMeasurement) {\n signJwtMeasurement.endMeasurement({\n success: true\n });\n }\n\n return signedJwt;\n }\n\n /**\n * Returns the SHA-256 hash of an input string\n * @param plainText\n */\n async hashString(plainText: string): Promise<string> {\n const hashBuffer: ArrayBuffer = await this.browserCrypto.sha256Digest(plainText);\n const hashBytes = new Uint8Array(hashBuffer);\n return this.b64Encode.urlEncodeArr(hashBytes);\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface ISubtleCrypto {
|
|
2
|
+
initPrng?(entropy: Uint8Array): void;
|
|
3
|
+
getRandomValues(dataBuffer: Uint8Array): Uint8Array;
|
|
4
|
+
generateKey(algorithm: RsaHashedKeyGenParams, extractable: boolean, keyUsages: KeyUsage[]): Promise<CryptoKeyPair>;
|
|
5
|
+
exportKey(key: CryptoKey): Promise<JsonWebKey>;
|
|
6
|
+
importKey(keyData: JsonWebKey, algorithm: RsaHashedImportParams, extractable: boolean, keyUsages: KeyUsage[]): Promise<CryptoKey>;
|
|
7
|
+
sign(algorithm: AlgorithmIdentifier, key: CryptoKey, data: ArrayBuffer): Promise<ArrayBuffer>;
|
|
8
|
+
digest(algorithm: AlgorithmIdentifier, data: Uint8Array): Promise<ArrayBuffer>;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=ISubtleCrypto.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ISubtleCrypto.d.ts","sourceRoot":"","sources":["../../src/crypto/ISubtleCrypto.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,aAAa;IAC1B,QAAQ,CAAC,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI,CAAC;IACrC,eAAe,CAAC,UAAU,EAAE,UAAU,GAAG,UAAU,CAAC;IACpD,WAAW,CAAC,SAAS,EAAE,qBAAqB,EAAE,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IACnH,SAAS,CAAC,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAC/C,SAAS,CAAC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,qBAAqB,EAAE,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAClI,IAAI,CAAC,SAAS,EAAE,mBAAmB,EAAE,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAC9F,MAAM,CAAC,SAAS,EAAE,mBAAmB,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;CAClF"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { ISubtleCrypto } from "./ISubtleCrypto";
|
|
2
|
+
export declare class ModernBrowserCrypto implements ISubtleCrypto {
|
|
3
|
+
getRandomValues(dataBuffer: Uint8Array): Uint8Array;
|
|
4
|
+
generateKey(algorithm: RsaHashedKeyGenParams, extractable: boolean, keyUsages: KeyUsage[]): Promise<CryptoKeyPair>;
|
|
5
|
+
exportKey(key: CryptoKey): Promise<JsonWebKey>;
|
|
6
|
+
importKey(keyData: JsonWebKey, algorithm: RsaHashedImportParams, extractable: boolean, keyUsages: KeyUsage[]): Promise<CryptoKey>;
|
|
7
|
+
sign(algorithm: AlgorithmIdentifier, key: CryptoKey, data: ArrayBuffer): Promise<ArrayBuffer>;
|
|
8
|
+
digest(algorithm: AlgorithmIdentifier, data: Uint8Array): Promise<ArrayBuffer>;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=ModernBrowserCrypto.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ModernBrowserCrypto.d.ts","sourceRoot":"","sources":["../../src/crypto/ModernBrowserCrypto.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,qBAAa,mBAAoB,YAAW,aAAa;IACrD,eAAe,CAAC,UAAU,EAAE,UAAU,GAAG,UAAU;IAI7C,WAAW,CAAC,SAAS,EAAE,qBAAqB,EAAE,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,aAAa,CAAC;IAIlH,SAAS,CAAC,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC;IAI9C,SAAS,CAAC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,qBAAqB,EAAE,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,SAAS,CAAC;IAIjI,IAAI,CAAC,SAAS,EAAE,mBAAmB,EAAE,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IAI7F,MAAM,CAAC,SAAS,EAAE,mBAAmB,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC;CAGvF"}
|