Skip to content

Commit

Permalink
Use Web Crypto for signing token requests on web
Browse files Browse the repository at this point in the history
TODO figure out secure context stuff and what the broad-reaching
implications are

Resolves #1295.

TODO what can we use as the statusCode and code — used generic "bad
request"
  • Loading branch information
lawrence-forooghian committed Jun 6, 2023
1 parent f8eeeb2 commit 645dec2
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 8 deletions.
8 changes: 6 additions & 2 deletions src/common/lib/client/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ class Auth {
if (useTokenAuth(options)) {
/* Token auth */
if (options.key && !hmac) {
// TODO what is this
const msg = 'client-side token request signing not supported';
Logger.logAction(Logger.LOG_ERROR, 'Auth()', msg);
throw new Error(msg);
Expand Down Expand Up @@ -413,6 +414,7 @@ class Auth {
callback: StandardCallback<API.Types.TokenDetails>
): void;

// TODO where is this called? it's public API but what else? _ensureValidAuthCredentials
requestToken(
tokenParams: API.Types.TokenParams | StandardCallback<API.Types.TokenDetails> | null,
authOptions?: any | StandardCallback<API.Types.TokenDetails>,
Expand Down Expand Up @@ -559,6 +561,7 @@ class Auth {
};
} else if (authOptions.key) {
Logger.logAction(Logger.LOG_MINOR, 'Auth.requestToken()', 'using token auth with client-side signing');
// TODO what is this?
tokenRequestCallback = (params: any, cb: Function) => {
this.createTokenRequest(params, authOptions, cb);
};
Expand Down Expand Up @@ -745,6 +748,7 @@ class Auth {
*
* @param callback
*/
// TODO who calls this? it's public API but other than that I don't think called anywhere else except requestToken
createTokenRequest(tokenParams: API.Types.TokenParams | null, authOptions: any, callback: Function) {
/* shuffle and normalise arguments as necessary */
if (typeof tokenParams == 'function' && !callback) {
Expand Down Expand Up @@ -829,8 +833,8 @@ class Auth {
callback(null, request);
})
.catch((err) => {
Logger.logAction(Logger.LOG_ERROR, 'Auth.getTokenRequest()', 'failed to sign request: ' + err.message);
callback(ErrorInfo.fromValues(err));
Logger.logAction(Logger.LOG_ERROR, 'Auth.getTokenRequest()', 'failed to sign request: ' + err);
callback(new ErrorInfo('Failed to sign token request: ' + err.message, 40000, 400));
});
});
}
Expand Down
10 changes: 4 additions & 6 deletions src/platform/web/lib/util/crypto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import ICipher from '../../../../common/types/ICipher';
import { CryptoDataTypes } from '../../../../common/types/cryptoDataTypes';
import BufferUtils, { Bufferlike, Output as BufferUtilsOutput } from './bufferutils';
import { IPlatformConfig } from 'common/types/IPlatformConfig';
import HmacSHA256 from 'crypto-js/build/hmac-sha256';

// The type to which ./msgpack.ts deserializes elements of the `bin` or `ext` type
type MessagePackBinaryType = ArrayBuffer;
Expand Down Expand Up @@ -212,12 +211,11 @@ var CryptoFactory = function (config: IPlatformConfig, bufferUtils: typeof Buffe
}

static async hmacSha256(message: InputPlaintext, key: API.Types.CipherKey): Promise<OutputCiphertext> {
const messageWordArray = bufferUtils.toWordArray(message);
const keyWordArray = bufferUtils.toWordArray(key);
// TODO what if crypto.subtle not available
const cryptoKey = await crypto.subtle.importKey('raw', key, { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);
const digest = await crypto.subtle.sign('HMAC', cryptoKey, message);

const digest = HmacSHA256(messageWordArray, keyWordArray);

return bufferUtils.toArrayBuffer(digest);
return digest;
}
}

Expand Down

0 comments on commit 645dec2

Please sign in to comment.