mirror of
https://github.com/bitwarden/browser.git
synced 2024-11-24 12:06:15 +01:00
clean up totp service
This commit is contained in:
parent
46ad445951
commit
4b85172b52
@ -6,7 +6,9 @@ import { TotpService as TotpServiceAbstraction } from '../abstractions/totp.serv
|
|||||||
|
|
||||||
import { Utils } from '../misc/utils';
|
import { Utils } from '../misc/utils';
|
||||||
|
|
||||||
const b32Chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';
|
const B32Chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';
|
||||||
|
const SteamChars = ['2', '3', '4', '5', '6', '7', '8', '9', 'B', 'C', 'D', 'F', 'G', 'H', 'J', 'K', 'M',
|
||||||
|
'N', 'P', 'Q', 'R', 'T', 'V', 'W', 'X', 'Y'];
|
||||||
|
|
||||||
export class TotpService implements TotpServiceAbstraction {
|
export class TotpService implements TotpServiceAbstraction {
|
||||||
constructor(private storageService: StorageService, private cryptoFunctionService: CryptoFunctionService) { }
|
constructor(private storageService: StorageService, private cryptoFunctionService: CryptoFunctionService) { }
|
||||||
@ -19,7 +21,9 @@ export class TotpService implements TotpServiceAbstraction {
|
|||||||
let alg: 'sha1' | 'sha256' | 'sha512' = 'sha1';
|
let alg: 'sha1' | 'sha256' | 'sha512' = 'sha1';
|
||||||
let digits = 6;
|
let digits = 6;
|
||||||
let keyB32 = key;
|
let keyB32 = key;
|
||||||
if (key.toLowerCase().indexOf('otpauth://') === 0) {
|
const isOtpAuth = key.toLowerCase().indexOf('otpauth://') === 0;
|
||||||
|
const isSteamAuth = !isOtpAuth && key.toLowerCase().indexOf('steam://') === 0;
|
||||||
|
if (isOtpAuth) {
|
||||||
const params = Utils.getQueryParams(key);
|
const params = Utils.getQueryParams(key);
|
||||||
if (params.has('digits') && params.get('digits') != null) {
|
if (params.has('digits') && params.get('digits') != null) {
|
||||||
try {
|
try {
|
||||||
@ -48,14 +52,14 @@ export class TotpService implements TotpServiceAbstraction {
|
|||||||
alg = algParam;
|
alg = algParam;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if(key.toLowerCase().indexOf('steam://') === 0) {
|
} else if (isSteamAuth) {
|
||||||
keyB32 = key.substr('steam://'.length);
|
keyB32 = key.substr('steam://'.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
const epoch = Math.round(new Date().getTime() / 1000.0);
|
const epoch = Math.round(new Date().getTime() / 1000.0);
|
||||||
const timeHex = this.leftpad(this.dec2hex(Math.floor(epoch / period)), 16, '0');
|
const timeHex = this.leftPad(this.decToHex(Math.floor(epoch / period)), 16, '0');
|
||||||
const timeBytes = Utils.fromHexToArray(timeHex);
|
const timeBytes = Utils.fromHexToArray(timeHex);
|
||||||
const keyBytes = this.b32tobytes(keyB32);
|
const keyBytes = this.b32ToBytes(keyB32);
|
||||||
|
|
||||||
if (!keyBytes.length || !timeBytes.length) {
|
if (!keyBytes.length || !timeBytes.length) {
|
||||||
return null;
|
return null;
|
||||||
@ -71,20 +75,18 @@ export class TotpService implements TotpServiceAbstraction {
|
|||||||
const binary = ((hash[offset] & 0x7f) << 24) | ((hash[offset + 1] & 0xff) << 16) |
|
const binary = ((hash[offset] & 0x7f) << 24) | ((hash[offset + 1] & 0xff) << 16) |
|
||||||
((hash[offset + 2] & 0xff) << 8) | (hash[offset + 3] & 0xff);
|
((hash[offset + 2] & 0xff) << 8) | (hash[offset + 3] & 0xff);
|
||||||
/* tslint:enable */
|
/* tslint:enable */
|
||||||
let otp = (binary % Math.pow(10, digits)).toString();
|
|
||||||
otp = this.leftpad(otp, digits, '0');
|
|
||||||
|
|
||||||
if(key.toLowerCase().indexOf('steam://') === 0) {
|
let otp = '';
|
||||||
const steamchars = [
|
if (isSteamAuth) {
|
||||||
'2', '3', '4', '5', '6', '7', '8', '9', 'B', 'C',
|
// tslint:disable-next-line
|
||||||
'D', 'F', 'G', 'H', 'J', 'K', 'M', 'N', 'P', 'Q',
|
let fullCode = binary & 0x7fffffff;
|
||||||
'R', 'T', 'V', 'W', 'X', 'Y'];
|
for (let i = 0; i < 5; i++) {
|
||||||
otp = "";
|
otp += SteamChars[fullCode % SteamChars.length];
|
||||||
let fullcode = binary & 0x7fffffff;
|
fullCode = Math.trunc(fullCode / SteamChars.length);
|
||||||
for (var i = 0; i < 5; i++) {
|
|
||||||
otp += steamchars[fullcode % steamchars.length];
|
|
||||||
fullcode = Math.trunc(fullcode / steamchars.length);
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
otp = (binary % Math.pow(10, digits)).toString();
|
||||||
|
otp = this.leftPad(otp, digits, '0');
|
||||||
}
|
}
|
||||||
|
|
||||||
return otp;
|
return otp;
|
||||||
@ -109,23 +111,23 @@ export class TotpService implements TotpServiceAbstraction {
|
|||||||
|
|
||||||
// Helpers
|
// Helpers
|
||||||
|
|
||||||
private leftpad(s: string, l: number, p: string): string {
|
private leftPad(s: string, l: number, p: string): string {
|
||||||
if (l + 1 >= s.length) {
|
if (l + 1 >= s.length) {
|
||||||
s = Array(l + 1 - s.length).join(p) + s;
|
s = Array(l + 1 - s.length).join(p) + s;
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
private dec2hex(d: number): string {
|
private decToHex(d: number): string {
|
||||||
return (d < 15.5 ? '0' : '') + Math.round(d).toString(16);
|
return (d < 15.5 ? '0' : '') + Math.round(d).toString(16);
|
||||||
}
|
}
|
||||||
|
|
||||||
private b32tohex(s: string): string {
|
private b32ToHex(s: string): string {
|
||||||
s = s.toUpperCase();
|
s = s.toUpperCase();
|
||||||
let cleanedInput = '';
|
let cleanedInput = '';
|
||||||
|
|
||||||
for (let i = 0; i < s.length; i++) {
|
for (let i = 0; i < s.length; i++) {
|
||||||
if (b32Chars.indexOf(s[i]) < 0) {
|
if (B32Chars.indexOf(s[i]) < 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,11 +138,11 @@ export class TotpService implements TotpServiceAbstraction {
|
|||||||
let bits = '';
|
let bits = '';
|
||||||
let hex = '';
|
let hex = '';
|
||||||
for (let i = 0; i < s.length; i++) {
|
for (let i = 0; i < s.length; i++) {
|
||||||
const byteIndex = b32Chars.indexOf(s.charAt(i));
|
const byteIndex = B32Chars.indexOf(s.charAt(i));
|
||||||
if (byteIndex < 0) {
|
if (byteIndex < 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
bits += this.leftpad(byteIndex.toString(2), 5, '0');
|
bits += this.leftPad(byteIndex.toString(2), 5, '0');
|
||||||
}
|
}
|
||||||
for (let i = 0; i + 4 <= bits.length; i += 4) {
|
for (let i = 0; i + 4 <= bits.length; i += 4) {
|
||||||
const chunk = bits.substr(i, 4);
|
const chunk = bits.substr(i, 4);
|
||||||
@ -149,8 +151,8 @@ export class TotpService implements TotpServiceAbstraction {
|
|||||||
return hex;
|
return hex;
|
||||||
}
|
}
|
||||||
|
|
||||||
private b32tobytes(s: string): Uint8Array {
|
private b32ToBytes(s: string): Uint8Array {
|
||||||
return Utils.fromHexToArray(this.b32tohex(s));
|
return Utils.fromHexToArray(this.b32ToHex(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
private async sign(keyBytes: Uint8Array, timeBytes: Uint8Array, alg: 'sha1' | 'sha256' | 'sha512') {
|
private async sign(keyBytes: Uint8Array, timeBytes: Uint8Array, alg: 'sha1' | 'sha256' | 'sha512') {
|
||||||
|
Loading…
Reference in New Issue
Block a user