2024-03-04 04:04:58 +03:00
|
|
|
import { BaseCryptoProvider, IAesCtr, ICryptoProvider, IEncryptionScheme } from '@mtcute/core/utils.js'
|
|
|
|
import {
|
|
|
|
createCtr256,
|
|
|
|
ctr256,
|
|
|
|
deflateMaxSize,
|
|
|
|
freeCtr256,
|
|
|
|
gunzip,
|
|
|
|
ige256Decrypt,
|
|
|
|
ige256Encrypt,
|
|
|
|
initSync,
|
|
|
|
sha1,
|
|
|
|
sha256,
|
|
|
|
} from '@mtcute/wasm'
|
2024-02-28 00:33:23 +03:00
|
|
|
|
|
|
|
import { loadWasmBinary, WasmInitInput } from './wasm.js'
|
2023-10-16 19:23:53 +03:00
|
|
|
|
|
|
|
const ALGO_TO_SUBTLE: Record<string, string> = {
|
|
|
|
sha256: 'SHA-256',
|
|
|
|
sha1: 'SHA-1',
|
|
|
|
sha512: 'SHA-512',
|
|
|
|
}
|
|
|
|
|
2024-02-28 00:33:23 +03:00
|
|
|
export interface WebCryptoProviderOptions {
|
|
|
|
crypto?: Crypto
|
|
|
|
wasmInput?: WasmInitInput
|
|
|
|
}
|
|
|
|
|
2024-03-04 04:04:58 +03:00
|
|
|
export class WebCryptoProvider extends BaseCryptoProvider implements ICryptoProvider {
|
2023-11-12 00:36:00 +03:00
|
|
|
readonly crypto: Crypto
|
2024-02-28 00:33:23 +03:00
|
|
|
private _wasmInput?: WasmInitInput
|
2023-10-16 19:23:53 +03:00
|
|
|
|
2024-03-04 04:04:58 +03:00
|
|
|
sha1(data: Uint8Array): Uint8Array {
|
|
|
|
return sha1(data)
|
|
|
|
}
|
|
|
|
|
|
|
|
sha256(data: Uint8Array): Uint8Array {
|
|
|
|
return sha256(data)
|
|
|
|
}
|
|
|
|
|
|
|
|
createAesCtr(key: Uint8Array, iv: Uint8Array): IAesCtr {
|
|
|
|
const ctx = createCtr256(key, iv)
|
|
|
|
|
|
|
|
return {
|
|
|
|
process: (data) => ctr256(ctx, data),
|
|
|
|
close: () => freeCtr256(ctx),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
createAesIge(key: Uint8Array, iv: Uint8Array): IEncryptionScheme {
|
|
|
|
return {
|
|
|
|
encrypt: (data) => ige256Encrypt(data, key, iv),
|
|
|
|
decrypt: (data) => ige256Decrypt(data, key, iv),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
gzip(data: Uint8Array, maxSize: number): Uint8Array | null {
|
|
|
|
return deflateMaxSize(data, maxSize)
|
|
|
|
}
|
|
|
|
|
|
|
|
gunzip(data: Uint8Array): Uint8Array {
|
|
|
|
return gunzip(data)
|
|
|
|
}
|
|
|
|
|
2024-02-28 00:33:23 +03:00
|
|
|
constructor(params?: WebCryptoProviderOptions) {
|
|
|
|
super()
|
2023-11-12 00:36:00 +03:00
|
|
|
const crypto = params?.crypto ?? globalThis.crypto
|
2023-10-16 19:23:53 +03:00
|
|
|
|
2023-11-12 00:36:00 +03:00
|
|
|
if (!crypto || !crypto.subtle) {
|
|
|
|
throw new Error('WebCrypto is not available')
|
2023-11-04 06:44:18 +03:00
|
|
|
}
|
2023-11-12 00:36:00 +03:00
|
|
|
this.crypto = crypto
|
2024-02-28 00:33:23 +03:00
|
|
|
this._wasmInput = params?.wasmInput
|
|
|
|
}
|
|
|
|
|
|
|
|
async initialize(): Promise<void> {
|
|
|
|
initSync(await loadWasmBinary(this._wasmInput))
|
2023-10-16 19:23:53 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
async pbkdf2(
|
|
|
|
password: Uint8Array,
|
|
|
|
salt: Uint8Array,
|
|
|
|
iterations: number,
|
|
|
|
keylen?: number | undefined,
|
|
|
|
algo?: string | undefined,
|
|
|
|
): Promise<Uint8Array> {
|
2023-11-12 00:36:00 +03:00
|
|
|
const keyMaterial = await this.crypto.subtle.importKey('raw', password, 'PBKDF2', false, ['deriveBits'])
|
2023-10-16 19:23:53 +03:00
|
|
|
|
2023-11-12 00:36:00 +03:00
|
|
|
return this.crypto.subtle
|
2023-10-16 19:23:53 +03:00
|
|
|
.deriveBits(
|
|
|
|
{
|
|
|
|
name: 'PBKDF2',
|
|
|
|
salt,
|
|
|
|
iterations,
|
|
|
|
hash: algo ? ALGO_TO_SUBTLE[algo] : 'SHA-512',
|
|
|
|
},
|
|
|
|
keyMaterial,
|
|
|
|
(keylen || 64) * 8,
|
|
|
|
)
|
|
|
|
.then((result) => new Uint8Array(result))
|
|
|
|
}
|
|
|
|
|
|
|
|
async hmacSha256(data: Uint8Array, key: Uint8Array): Promise<Uint8Array> {
|
2023-11-12 00:36:00 +03:00
|
|
|
const keyMaterial = await this.crypto.subtle.importKey(
|
2023-10-16 19:23:53 +03:00
|
|
|
'raw',
|
|
|
|
key,
|
|
|
|
{ name: 'HMAC', hash: { name: 'SHA-256' } },
|
|
|
|
false,
|
|
|
|
['sign'],
|
|
|
|
)
|
|
|
|
|
2023-11-12 00:36:00 +03:00
|
|
|
const res = await this.crypto.subtle.sign({ name: 'HMAC' }, keyMaterial, data)
|
2023-10-16 19:23:53 +03:00
|
|
|
|
|
|
|
return new Uint8Array(res)
|
|
|
|
}
|
2023-11-12 00:36:00 +03:00
|
|
|
|
|
|
|
randomFill(buf: Uint8Array): void {
|
|
|
|
this.crypto.getRandomValues(buf)
|
|
|
|
}
|
2023-10-16 19:23:53 +03:00
|
|
|
}
|